From 7908492aabf12980a22bd9535f0149110b58bed9 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Fri, 5 Apr 2024 22:06:13 -0600 Subject: [PATCH 01/13] Showing number of felts and size in bytes per built contract --- bin/sozo/src/commands/build.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index bb45c1f6c4..e3c72ea479 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -4,6 +4,10 @@ use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; +use starknet::core::types::contract::SierraClass; +use std::fs; +use std::fs::File; +use std::path::PathBuf; #[derive(Args, Debug)] pub struct BuildArgs { @@ -18,6 +22,10 @@ pub struct BuildArgs { #[arg(long)] #[arg(help = "Output directory.", default_value = "bindings")] pub bindings_output: String, + + #[arg(long)] + #[arg(help = "Report of all built contracts statistics")] + pub stats: bool, } impl BuildArgs { @@ -36,6 +44,31 @@ impl BuildArgs { builtin_plugins.push(BuiltinPlugins::Unity); } + if self.stats { + let built_contract_paths: fs::ReadDir = + fs::read_dir(compile_info.target_dir.as_str()).unwrap(); + + println!("\n"); + for sierra_json_path in built_contract_paths { + let sierra_json_path: PathBuf = sierra_json_path.unwrap().path(); + let filename = sierra_json_path.file_name().unwrap(); + println!( + "---------------Contract Stats for {}---------------\n", + filename.to_str().unwrap() + ); + let file = File::open(sierra_json_path)?; + let contract_artifact: SierraClass = serde_json::from_reader(&file)?; + let contract_artifact = contract_artifact.flatten()?; + + println!( + "- Contract bytecode size (Number of felts in the program): {}", + contract_artifact.sierra_program.iter().count() + ); + + println!("- Contract Class size: {} bytes \n", file.metadata().unwrap().len()); + } + } + // Custom plugins are always empty for now. let bindgen = PluginManager { profile_name: compile_info.profile_name, From 0d4618f04d9c7b9536bc5e9704d542c489176ed6 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 8 Apr 2024 13:39:57 -0600 Subject: [PATCH 02/13] Creation of statistics.rs file and move some of the logic to compute statistics. --- bin/sozo/src/commands/build.rs | 31 ++++++++++--------- bin/sozo/src/commands/options/mod.rs | 1 + bin/sozo/src/commands/options/statistics.rs | 34 +++++++++++++++++++++ 3 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 bin/sozo/src/commands/options/statistics.rs diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index e3c72ea479..bd5c70c5e2 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -4,11 +4,14 @@ use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; -use starknet::core::types::contract::SierraClass; -use std::fs; -use std::fs::File; +use std::fs::{self, File}; use std::path::PathBuf; +use super::options::statistics::compute_contract_byte_code_size; +use super::options::statistics::get_file_size_in_bytes; +use super::options::statistics::read_sierra_json_program; +use super::options::statistics::Stats; + #[derive(Args, Debug)] pub struct BuildArgs { #[arg(long)] @@ -23,9 +26,8 @@ pub struct BuildArgs { #[arg(help = "Output directory.", default_value = "bindings")] pub bindings_output: String, - #[arg(long)] - #[arg(help = "Report of all built contracts statistics")] - pub stats: bool, + #[command(flatten)] + pub stats: Stats, } impl BuildArgs { @@ -44,11 +46,9 @@ impl BuildArgs { builtin_plugins.push(BuiltinPlugins::Unity); } - if self.stats { + if self.stats.stats { let built_contract_paths: fs::ReadDir = fs::read_dir(compile_info.target_dir.as_str()).unwrap(); - - println!("\n"); for sierra_json_path in built_contract_paths { let sierra_json_path: PathBuf = sierra_json_path.unwrap().path(); let filename = sierra_json_path.file_name().unwrap(); @@ -56,17 +56,20 @@ impl BuildArgs { "---------------Contract Stats for {}---------------\n", filename.to_str().unwrap() ); - let file = File::open(sierra_json_path)?; - let contract_artifact: SierraClass = serde_json::from_reader(&file)?; - let contract_artifact = contract_artifact.flatten()?; + let sierra_json_file = File::open(sierra_json_path)?; + let contract_artifact = read_sierra_json_program(&sierra_json_file)?; + let number_of_felts = compute_contract_byte_code_size(contract_artifact); + let file_size = get_file_size_in_bytes(sierra_json_file); println!( "- Contract bytecode size (Number of felts in the program): {}", - contract_artifact.sierra_program.iter().count() + number_of_felts ); - println!("- Contract Class size: {} bytes \n", file.metadata().unwrap().len()); + println!("- Contract Class size: {} bytes \n", file_size); } + } else if !self.stats.stats_limits.is_none() { + println!("When using custom limits") } // Custom plugins are always empty for now. diff --git a/bin/sozo/src/commands/options/mod.rs b/bin/sozo/src/commands/options/mod.rs index 0bd599bcc1..e997108381 100644 --- a/bin/sozo/src/commands/options/mod.rs +++ b/bin/sozo/src/commands/options/mod.rs @@ -1,5 +1,6 @@ pub mod account; pub mod starknet; +pub mod statistics; pub mod transaction; pub mod world; diff --git a/bin/sozo/src/commands/options/statistics.rs b/bin/sozo/src/commands/options/statistics.rs new file mode 100644 index 0000000000..f01267946c --- /dev/null +++ b/bin/sozo/src/commands/options/statistics.rs @@ -0,0 +1,34 @@ +use anyhow::Result; +use clap::Args; +use starknet::core::types::contract::SierraClass; +use starknet::core::types::FlattenedSierraClass; +use std::fs::File; + +#[derive(Debug, Args)] +#[group(required = false, multiple = false)] +pub struct Stats { + #[arg(long, help = "Display statistics")] + pub stats: bool, + + #[arg( + long, + value_name = "FILE", + help = "Specify a JSON file with custom limits for statistics" + )] + pub stats_limits: Option, +} + +pub fn read_sierra_json_program(file: &File) -> Result { + let contract_artifact: SierraClass = serde_json::from_reader(file)?; + let contract_artifact: FlattenedSierraClass = contract_artifact.flatten()?; + + Ok(contract_artifact) +} + +pub fn compute_contract_byte_code_size(contract_artifact: FlattenedSierraClass) -> usize { + contract_artifact.sierra_program.iter().count() +} + +pub fn get_file_size_in_bytes(file: File) -> u64 { + file.metadata().unwrap().len() +} From 877b6112db42c37732653002d3e7e83e607eb457 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 8 Apr 2024 15:44:52 -0600 Subject: [PATCH 03/13] Refactor moving more logic to statistics.rs --- bin/sozo/src/commands/build.rs | 42 +++++++-------- bin/sozo/src/commands/options/statistics.rs | 57 ++++++++++++++++++++- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index bd5c70c5e2..bc52a16e6b 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -1,15 +1,13 @@ use anyhow::Result; + use clap::Args; use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; -use std::fs::{self, File}; -use std::path::PathBuf; -use super::options::statistics::compute_contract_byte_code_size; -use super::options::statistics::get_file_size_in_bytes; -use super::options::statistics::read_sierra_json_program; +use crate::commands::options::statistics::get_contract_statistics_for_dir; + use super::options::statistics::Stats; #[derive(Args, Debug)] @@ -32,7 +30,7 @@ pub struct BuildArgs { impl BuildArgs { pub fn run(self, config: &Config) -> Result<()> { - let compile_info = compile_workspace( + let compile_info: dojo_lang::scarb_internal::CompileInfo = compile_workspace( config, CompileOpts { include_targets: vec![], exclude_targets: vec![TargetKind::TEST] }, )?; @@ -46,30 +44,22 @@ impl BuildArgs { builtin_plugins.push(BuiltinPlugins::Unity); } - if self.stats.stats { - let built_contract_paths: fs::ReadDir = - fs::read_dir(compile_info.target_dir.as_str()).unwrap(); - for sierra_json_path in built_contract_paths { - let sierra_json_path: PathBuf = sierra_json_path.unwrap().path(); - let filename = sierra_json_path.file_name().unwrap(); + if self.stats.stats || !self.stats.stats_limits.is_none() { + let contract_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); + + for contract_stats in contract_statistics { println!( "---------------Contract Stats for {}---------------\n", - filename.to_str().unwrap() + contract_stats.contract_name ); - let sierra_json_file = File::open(sierra_json_path)?; - let contract_artifact = read_sierra_json_program(&sierra_json_file)?; - let number_of_felts = compute_contract_byte_code_size(contract_artifact); - let file_size = get_file_size_in_bytes(sierra_json_file); println!( "- Contract bytecode size (Number of felts in the program): {}", - number_of_felts + contract_stats.number_felts ); - println!("- Contract Class size: {} bytes \n", file_size); + println!("- Contract Class size: {} bytes \n", contract_stats.file_size); } - } else if !self.stats.stats_limits.is_none() { - println!("When using custom limits") } // Custom plugins are always empty for now. @@ -97,14 +87,20 @@ impl BuildArgs { mod tests { use dojo_test_utils::compiler::build_test_config; + use crate::commands::options::statistics::Stats; + use super::BuildArgs; #[test] fn build_example_with_typescript_and_unity_bindings() { let config = build_test_config("../../examples/spawn-and-move/Scarb.toml").unwrap(); - let build_args = - BuildArgs { bindings_output: "generated".to_string(), typescript: true, unity: true }; + let build_args = BuildArgs { + bindings_output: "generated".to_string(), + typescript: true, + unity: true, + stats: Stats { stats: false, stats_limits: None }, + }; let result = build_args.run(&config); assert!(result.is_ok()); } diff --git a/bin/sozo/src/commands/options/statistics.rs b/bin/sozo/src/commands/options/statistics.rs index f01267946c..faed3249ba 100644 --- a/bin/sozo/src/commands/options/statistics.rs +++ b/bin/sozo/src/commands/options/statistics.rs @@ -1,8 +1,18 @@ use anyhow::Result; +use camino::Utf8PathBuf; use clap::Args; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; -use std::fs::File; +use std::{ + fs::{self, File}, + path::PathBuf, +}; + +pub struct ContractStatistics { + pub contract_name: String, + pub number_felts: usize, + pub file_size: u64, +} #[derive(Debug, Args)] #[group(required = false, multiple = false)] @@ -32,3 +42,48 @@ pub fn compute_contract_byte_code_size(contract_artifact: FlattenedSierraClass) pub fn get_file_size_in_bytes(file: File) -> u64 { file.metadata().unwrap().len() } + +pub fn get_contract_statistics_for_file( + file_name: String, + sierra_json_file: File, + contract_artifact: FlattenedSierraClass, +) -> ContractStatistics { + ContractStatistics { + contract_name: file_name, + number_felts: compute_contract_byte_code_size(contract_artifact), + file_size: get_file_size_in_bytes(sierra_json_file), + } +} + +pub fn get_contract_statistics_for_dir(target_directory: &Utf8PathBuf) -> Vec { + let mut contract_statistics = Vec::new(); + let built_contract_paths: fs::ReadDir = fs::read_dir(target_directory.as_str()).unwrap(); + for sierra_json_path in built_contract_paths { + let sierra_json_path: PathBuf = sierra_json_path.unwrap().path(); + + let sierra_json_file: File = match File::open(&sierra_json_path) { + Ok(file) => file, + Err(_) => { + println!("Error opening Sierra JSON file: {}", sierra_json_path.display()); + continue; // Skip this file and proceed with the next one + } + }; + + let contract_artifact: FlattenedSierraClass = + match read_sierra_json_program(&sierra_json_file) { + Ok(artifact) => artifact, + Err(_) => { + println!("Error reading Sierra JSON program: {}", sierra_json_path.display()); + continue; // Skip this file and proceed with the next one + } + }; + + let filename = sierra_json_path.file_name().unwrap(); + contract_statistics.push(get_contract_statistics_for_file( + filename.to_string_lossy().to_string(), + sierra_json_file, + contract_artifact, + )); + } + contract_statistics +} From ede5edee5ae68c222bbf8d590cfffcb541780e1c Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 8 Apr 2024 17:46:19 -0600 Subject: [PATCH 04/13] 1- Creation of starknet_constants.json file 2- Print stats method in build.rs 3- Compare_agains_limit in statistics.rs --- bin/sozo/resources/starknet_constants.json | 4 ++ bin/sozo/src/commands/build.rs | 64 +++++++++++++++------ bin/sozo/src/commands/options/statistics.rs | 22 ++++++- 3 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 bin/sozo/resources/starknet_constants.json diff --git a/bin/sozo/resources/starknet_constants.json b/bin/sozo/resources/starknet_constants.json new file mode 100644 index 0000000000..0859b936c1 --- /dev/null +++ b/bin/sozo/resources/starknet_constants.json @@ -0,0 +1,4 @@ +{ + "max_contract_bytecode_size": 81290, + "max_contract_class_size": 4089446 +} \ No newline at end of file diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index bc52a16e6b..75b5843715 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -1,14 +1,22 @@ use anyhow::Result; - use clap::Args; use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; +use std::fs::File; + +use crate::commands::options::statistics::{ + compare_against_limit, get_contract_statistics_for_dir, +}; -use crate::commands::options::statistics::get_contract_statistics_for_dir; +use super::options::statistics::{ContractStatistics, Stats}; -use super::options::statistics::Stats; +#[derive(Debug, serde::Deserialize)] +pub struct StarknetConstants { + max_contract_bytecode_size: u64, + max_contract_class_size: u64, +} #[derive(Args, Debug)] pub struct BuildArgs { @@ -45,20 +53,18 @@ impl BuildArgs { } if self.stats.stats || !self.stats.stats_limits.is_none() { - let contract_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); - - for contract_stats in contract_statistics { - println!( - "---------------Contract Stats for {}---------------\n", - contract_stats.contract_name - ); - - println!( - "- Contract bytecode size (Number of felts in the program): {}", - contract_stats.number_felts - ); - - println!("- Contract Class size: {} bytes \n", contract_stats.file_size); + const STARKNET_CONSTANTS_JSON: &str = "resources/starknet_constants.json"; + let json_consts_path = match &self.stats.stats_limits { + Some(path) => path.clone(), + None => String::from(STARKNET_CONSTANTS_JSON), + }; + + let file = File::open(&json_consts_path)?; + let limits: StarknetConstants = serde_json::from_reader(&file)?; + let contracts_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); + + for contract_stats in contracts_statistics { + print_stats(contract_stats, &limits); } } @@ -83,6 +89,30 @@ impl BuildArgs { } } +pub fn print_stats(contract_statistic: ContractStatistics, limits: &StarknetConstants) { + println!( + "---------------Contract Stats for {}---------------", + contract_statistic.contract_name + ); + + print!( + "- Contract bytecode size (Number of felts in the program): {} ", + contract_statistic.number_felts, + ); + println!( + "{}", + compare_against_limit(contract_statistic.number_felts, limits.max_contract_bytecode_size) + ); + println!(""); + + print!("- Contract Class size: {} bytes ", contract_statistic.file_size); + println!( + "{}", + compare_against_limit(contract_statistic.file_size, limits.max_contract_class_size) + ); + println!(""); +} + #[cfg(test)] mod tests { use dojo_test_utils::compiler::build_test_config; diff --git a/bin/sozo/src/commands/options/statistics.rs b/bin/sozo/src/commands/options/statistics.rs index faed3249ba..288c4267fb 100644 --- a/bin/sozo/src/commands/options/statistics.rs +++ b/bin/sozo/src/commands/options/statistics.rs @@ -10,7 +10,7 @@ use std::{ pub struct ContractStatistics { pub contract_name: String, - pub number_felts: usize, + pub number_felts: u64, pub file_size: u64, } @@ -50,7 +50,7 @@ pub fn get_contract_statistics_for_file( ) -> ContractStatistics { ContractStatistics { contract_name: file_name, - number_felts: compute_contract_byte_code_size(contract_artifact), + number_felts: compute_contract_byte_code_size(contract_artifact) as u64, file_size: get_file_size_in_bytes(sierra_json_file), } } @@ -87,3 +87,21 @@ pub fn get_contract_statistics_for_dir(target_directory: &Utf8PathBuf) -> Vec String { + let warning_threshold = (limit as f64 * 0.8) as u64; + let mut buffer = String::new(); + + if num1 > limit { + buffer.push_str("\x1b[0;31mDANGER\x1b[0m"); // Red color + buffer.push_str(&format!("! You have passed the starknet limit of {}", limit)); + } else if num1 > warning_threshold { + buffer.push_str("\x1b[0;33mWARNING\x1b[0m"); // Yellow color + buffer.push_str(&format!("! You have reached 80% of the starknet limit of {}", limit)); + } else { + buffer.push_str("\x1b[0;32mOK\x1b[0m"); // Green color + buffer.push_str(" No warnings."); + } + + buffer +} From 5e0e1b65a3b96ca1aeafde86da76b66d83c0239e Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 8 Apr 2024 19:44:54 -0600 Subject: [PATCH 05/13] Some fixes mentioned by clippy and rust_fmt.sh --- bin/sozo/src/commands/build.rs | 15 ++++++--------- bin/sozo/src/commands/options/statistics.rs | 9 ++++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index 75b5843715..99270b8a25 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -1,17 +1,17 @@ +use std::fs::File; + use anyhow::Result; use clap::Args; use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; -use std::fs::File; +use super::options::statistics::{ContractStatistics, Stats}; use crate::commands::options::statistics::{ compare_against_limit, get_contract_statistics_for_dir, }; -use super::options::statistics::{ContractStatistics, Stats}; - #[derive(Debug, serde::Deserialize)] pub struct StarknetConstants { max_contract_bytecode_size: u64, @@ -52,14 +52,14 @@ impl BuildArgs { builtin_plugins.push(BuiltinPlugins::Unity); } - if self.stats.stats || !self.stats.stats_limits.is_none() { + if self.stats.stats || self.stats.stats_limits.is_some() { const STARKNET_CONSTANTS_JSON: &str = "resources/starknet_constants.json"; let json_consts_path = match &self.stats.stats_limits { Some(path) => path.clone(), None => String::from(STARKNET_CONSTANTS_JSON), }; - let file = File::open(&json_consts_path)?; + let file = File::open(json_consts_path)?; let limits: StarknetConstants = serde_json::from_reader(&file)?; let contracts_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); @@ -103,23 +103,20 @@ pub fn print_stats(contract_statistic: ContractStatistics, limits: &StarknetCons "{}", compare_against_limit(contract_statistic.number_felts, limits.max_contract_bytecode_size) ); - println!(""); print!("- Contract Class size: {} bytes ", contract_statistic.file_size); println!( "{}", compare_against_limit(contract_statistic.file_size, limits.max_contract_class_size) ); - println!(""); } #[cfg(test)] mod tests { use dojo_test_utils::compiler::build_test_config; - use crate::commands::options::statistics::Stats; - use super::BuildArgs; + use crate::commands::options::statistics::Stats; #[test] fn build_example_with_typescript_and_unity_bindings() { diff --git a/bin/sozo/src/commands/options/statistics.rs b/bin/sozo/src/commands/options/statistics.rs index 288c4267fb..579fae5ab3 100644 --- a/bin/sozo/src/commands/options/statistics.rs +++ b/bin/sozo/src/commands/options/statistics.rs @@ -1,12 +1,11 @@ +use std::fs::{self, File}; +use std::path::PathBuf; + use anyhow::Result; use camino::Utf8PathBuf; use clap::Args; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; -use std::{ - fs::{self, File}, - path::PathBuf, -}; pub struct ContractStatistics { pub contract_name: String, @@ -36,7 +35,7 @@ pub fn read_sierra_json_program(file: &File) -> Result { } pub fn compute_contract_byte_code_size(contract_artifact: FlattenedSierraClass) -> usize { - contract_artifact.sierra_program.iter().count() + contract_artifact.sierra_program.len() } pub fn get_file_size_in_bytes(file: File) -> u64 { From 13381976660863e1c9bc3ce322f5080629099414 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Tue, 9 Apr 2024 15:08:59 -0600 Subject: [PATCH 06/13] Delete limit/comparison logic and output --- bin/sozo/resources/starknet_constants.json | 4 -- bin/sozo/src/commands/build.rs | 43 ++++----------------- bin/sozo/src/commands/options/statistics.rs | 26 ------------- 3 files changed, 8 insertions(+), 65 deletions(-) delete mode 100644 bin/sozo/resources/starknet_constants.json diff --git a/bin/sozo/resources/starknet_constants.json b/bin/sozo/resources/starknet_constants.json deleted file mode 100644 index 0859b936c1..0000000000 --- a/bin/sozo/resources/starknet_constants.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "max_contract_bytecode_size": 81290, - "max_contract_class_size": 4089446 -} \ No newline at end of file diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index 99270b8a25..e156a0df88 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -1,5 +1,3 @@ -use std::fs::File; - use anyhow::Result; use clap::Args; use dojo_bindgen::{BuiltinPlugins, PluginManager}; @@ -8,16 +6,7 @@ use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; use super::options::statistics::{ContractStatistics, Stats}; -use crate::commands::options::statistics::{ - compare_against_limit, get_contract_statistics_for_dir, -}; - -#[derive(Debug, serde::Deserialize)] -pub struct StarknetConstants { - max_contract_bytecode_size: u64, - max_contract_class_size: u64, -} - +use crate::commands::options::statistics::get_contract_statistics_for_dir; #[derive(Args, Debug)] pub struct BuildArgs { #[arg(long)] @@ -52,19 +41,11 @@ impl BuildArgs { builtin_plugins.push(BuiltinPlugins::Unity); } - if self.stats.stats || self.stats.stats_limits.is_some() { - const STARKNET_CONSTANTS_JSON: &str = "resources/starknet_constants.json"; - let json_consts_path = match &self.stats.stats_limits { - Some(path) => path.clone(), - None => String::from(STARKNET_CONSTANTS_JSON), - }; - - let file = File::open(json_consts_path)?; - let limits: StarknetConstants = serde_json::from_reader(&file)?; + if self.stats.stats { let contracts_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); for contract_stats in contracts_statistics { - print_stats(contract_stats, &limits); + print_stats(contract_stats); } } @@ -89,26 +70,18 @@ impl BuildArgs { } } -pub fn print_stats(contract_statistic: ContractStatistics, limits: &StarknetConstants) { +pub fn print_stats(contract_statistic: ContractStatistics) { println!( "---------------Contract Stats for {}---------------", contract_statistic.contract_name ); - print!( - "- Contract bytecode size (Number of felts in the program): {} ", - contract_statistic.number_felts, - ); println!( - "{}", - compare_against_limit(contract_statistic.number_felts, limits.max_contract_bytecode_size) + "- Contract bytecode size (Number of felts in the program): {}\n", + contract_statistic.number_felts, ); - print!("- Contract Class size: {} bytes ", contract_statistic.file_size); - println!( - "{}", - compare_against_limit(contract_statistic.file_size, limits.max_contract_class_size) - ); + println!("- Contract Class size: {} bytes\n", contract_statistic.file_size); } #[cfg(test)] @@ -126,7 +99,7 @@ mod tests { bindings_output: "generated".to_string(), typescript: true, unity: true, - stats: Stats { stats: false, stats_limits: None }, + stats: Stats { stats: false }, }; let result = build_args.run(&config); assert!(result.is_ok()); diff --git a/bin/sozo/src/commands/options/statistics.rs b/bin/sozo/src/commands/options/statistics.rs index 579fae5ab3..2b9cde440f 100644 --- a/bin/sozo/src/commands/options/statistics.rs +++ b/bin/sozo/src/commands/options/statistics.rs @@ -14,17 +14,9 @@ pub struct ContractStatistics { } #[derive(Debug, Args)] -#[group(required = false, multiple = false)] pub struct Stats { #[arg(long, help = "Display statistics")] pub stats: bool, - - #[arg( - long, - value_name = "FILE", - help = "Specify a JSON file with custom limits for statistics" - )] - pub stats_limits: Option, } pub fn read_sierra_json_program(file: &File) -> Result { @@ -86,21 +78,3 @@ pub fn get_contract_statistics_for_dir(target_directory: &Utf8PathBuf) -> Vec String { - let warning_threshold = (limit as f64 * 0.8) as u64; - let mut buffer = String::new(); - - if num1 > limit { - buffer.push_str("\x1b[0;31mDANGER\x1b[0m"); // Red color - buffer.push_str(&format!("! You have passed the starknet limit of {}", limit)); - } else if num1 > warning_threshold { - buffer.push_str("\x1b[0;33mWARNING\x1b[0m"); // Yellow color - buffer.push_str(&format!("! You have reached 80% of the starknet limit of {}", limit)); - } else { - buffer.push_str("\x1b[0;32mOK\x1b[0m"); // Green color - buffer.push_str(" No warnings."); - } - - buffer -} From 9bb996feec3a09e1ba5b7cf8dfe87060994fa1c4 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Tue, 9 Apr 2024 20:05:32 -0600 Subject: [PATCH 07/13] Add unit tests --- bin/sozo/src/commands/build.rs | 16 +- bin/sozo/src/commands/options/statistics.rs | 102 ++ .../contracts_test.contract_class.json | 1113 +++++++++++++++++ 3 files changed, 1229 insertions(+), 2 deletions(-) create mode 100644 bin/sozo/tests/test_data/sierra_compiled_contracts/contracts_test.contract_class.json diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index e156a0df88..507ab39ea3 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -88,8 +88,8 @@ pub fn print_stats(contract_statistic: ContractStatistics) { mod tests { use dojo_test_utils::compiler::build_test_config; - use super::BuildArgs; - use crate::commands::options::statistics::Stats; + use super::{print_stats, BuildArgs}; + use crate::commands::options::statistics::{ContractStatistics, Stats}; #[test] fn build_example_with_typescript_and_unity_bindings() { @@ -104,4 +104,16 @@ mod tests { let result = build_args.run(&config); assert!(result.is_ok()); } + + #[test] + fn test_print_stats() { + // Arrange + let contract_statistic = ContractStatistics { + contract_name: String::from("SampleContract"), + number_felts: 100, + file_size: 1024, + }; + // Act + print_stats(contract_statistic); + } } diff --git a/bin/sozo/src/commands/options/statistics.rs b/bin/sozo/src/commands/options/statistics.rs index 2b9cde440f..810cbdc364 100644 --- a/bin/sozo/src/commands/options/statistics.rs +++ b/bin/sozo/src/commands/options/statistics.rs @@ -7,6 +7,7 @@ use clap::Args; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; +#[derive(Debug, PartialEq)] pub struct ContractStatistics { pub contract_name: String, pub number_felts: u64, @@ -78,3 +79,104 @@ pub fn get_contract_statistics_for_dir(target_directory: &Utf8PathBuf) -> Vec" + ], + [ + 2, + "Const" + ], + [ + 3, + "Unit" + ], + [ + 4, + "core::bool" + ], + [ + 5, + "Const" + ], + [ + 6, + "ContractAddress" + ], + [ + 7, + "Box" + ], + [ + 8, + "Box" + ], + [ + 9, + "felt252" + ], + [ + 10, + "u128" + ], + [ + 11, + "Array" + ], + [ + 12, + "Snapshot>" + ], + [ + 13, + "core::array::Span::" + ], + [ + 14, + "Array" + ], + [ + 15, + "Snapshot>" + ], + [ + 16, + "core::array::Span::" + ], + [ + 17, + "u32" + ], + [ + 18, + "core::starknet::info::v2::TxInfo" + ], + [ + 19, + "u64" + ], + [ + 20, + "core::starknet::info::BlockInfo" + ], + [ + 21, + "core::starknet::info::v2::ResourceBounds" + ], + [ + 22, + "core::starknet::info::v2::ExecutionInfo" + ], + [ + 23, + "Box" + ], + [ + 24, + "Const" + ], + [ + 25, + "NonZero" + ], + [ + 26, + "Tuple" + ], + [ + 27, + "Const" + ], + [ + 28, + "StorageAddress" + ], + [ + 29, + "StorageBaseAddress" + ], + [ + 30, + "Const" + ], + [ + 31, + "Const" + ], + [ + 32, + "Tuple>" + ], + [ + 33, + "contracts::VotingContract::__member_module_yes_votes::ContractMemberState" + ], + [ + 34, + "contracts::VotingContract::__member_module_no_votes::ContractMemberState" + ], + [ + 35, + "contracts::VotingContract::__member_module_voters::ContractMemberState" + ], + [ + 36, + "contracts::VotingContract::ContractState" + ], + [ + 37, + "Tuple" + ], + [ + 38, + "core::panics::Panic" + ], + [ + 39, + "Tuple>" + ], + [ + 40, + "core::panics::PanicResult::<(contracts::VotingContract::ContractState, ())>" + ], + [ + 41, + "BuiltinCosts" + ], + [ + 42, + "System" + ], + [ + 43, + "Pedersen" + ], + [ + 44, + "core::panics::PanicResult::<(core::array::Span::,)>" + ], + [ + 45, + "Const" + ], + [ + 46, + "core::option::Option::" + ], + [ + 47, + "Box" + ], + [ + 48, + "GasBuiltin" + ] + ], + "libfunc_names": [ + [ + 0, + "revoke_ap_tracking" + ], + [ + 1, + "withdraw_gas" + ], + [ + 2, + "branch_align" + ], + [ + 3, + "struct_deconstruct>" + ], + [ + 4, + "enable_ap_tracking" + ], + [ + 5, + "store_temp" + ], + [ + 6, + "array_snapshot_pop_front" + ], + [ + 7, + "unbox" + ], + [ + 8, + "rename" + ], + [ + 9, + "enum_init, 0>" + ], + [ + 10, + "store_temp>>" + ], + [ + 11, + "store_temp>" + ], + [ + 12, + "jump" + ], + [ + 13, + "struct_construct" + ], + [ + 14, + "enum_init, 1>" + ], + [ + 15, + "enum_match>" + ], + [ + 16, + "disable_ap_tracking" + ], + [ + 17, + "drop>>" + ], + [ + 18, + "drop>" + ], + [ + 19, + "drop" + ], + [ + 20, + "array_new" + ], + [ + 21, + "const_as_immediate>" + ], + [ + 22, + "store_temp" + ], + [ + 23, + "array_append" + ], + [ + 24, + "struct_construct" + ], + [ + 25, + "struct_construct>>" + ], + [ + 26, + "enum_init,)>, 1>" + ], + [ + 27, + "store_temp" + ], + [ + 28, + "store_temp" + ], + [ + 29, + "store_temp" + ], + [ + 30, + "store_temp,)>>" + ], + [ + 31, + "get_builtin_costs" + ], + [ + 32, + "store_temp" + ], + [ + 33, + "withdraw_gas_all" + ], + [ + 34, + "struct_construct" + ], + [ + 35, + "struct_construct" + ], + [ + 36, + "struct_construct" + ], + [ + 37, + "struct_construct" + ], + [ + 38, + "function_call" + ], + [ + 39, + "enum_match>" + ], + [ + 40, + "drop>" + ], + [ + 41, + "snapshot_take>" + ], + [ + 42, + "drop>" + ], + [ + 43, + "struct_construct>" + ], + [ + 44, + "struct_construct>>" + ], + [ + 45, + "enum_init,)>, 0>" + ], + [ + 46, + "const_as_immediate>" + ], + [ + 47, + "drop" + ], + [ + 48, + "const_as_immediate>" + ], + [ + 49, + "drop>" + ], + [ + 50, + "storage_base_address_const<1142602927098787396562020832295408108705589548626984240874450201634165370313>" + ], + [ + 51, + "storage_address_from_base" + ], + [ + 52, + "const_as_immediate>" + ], + [ + 53, + "store_temp" + ], + [ + 54, + "store_temp" + ], + [ + 55, + "storage_read_syscall" + ], + [ + 56, + "storage_base_address_const<1683840052101120209483954731935227110542988872268356551521531283411842599347>" + ], + [ + 57, + "struct_construct>" + ], + [ + 58, + "snapshot_take>" + ], + [ + 59, + "drop>" + ], + [ + 60, + "struct_deconstruct>" + ], + [ + 61, + "store_temp>" + ], + [ + 62, + "dup" + ], + [ + 63, + "felt252_is_zero" + ], + [ + 64, + "drop>" + ], + [ + 65, + "const_as_immediate>" + ], + [ + 66, + "felt252_sub" + ], + [ + 67, + "get_execution_info_v2_syscall" + ], + [ + 68, + "store_temp>" + ], + [ + 69, + "unbox" + ], + [ + 70, + "struct_deconstruct" + ], + [ + 71, + "drop>" + ], + [ + 72, + "drop>" + ], + [ + 73, + "drop" + ], + [ + 74, + "store_temp" + ], + [ + 75, + "dup" + ], + [ + 76, + "contract_address_to_felt252" + ], + [ + 77, + "const_as_immediate>" + ], + [ + 78, + "pedersen" + ], + [ + 79, + "storage_base_address_from_felt252" + ], + [ + 80, + "enum_init" + ], + [ + 81, + "store_temp" + ], + [ + 82, + "enum_init" + ], + [ + 83, + "bool_not_impl" + ], + [ + 84, + "enum_match" + ], + [ + 85, + "felt252_add" + ], + [ + 86, + "storage_write_syscall" + ], + [ + 87, + "drop" + ], + [ + 88, + "enum_init, 1>" + ], + [ + 89, + "store_temp>" + ], + [ + 90, + "rename" + ], + [ + 91, + "rename" + ], + [ + 92, + "bool_to_felt252" + ], + [ + 93, + "struct_construct>" + ], + [ + 94, + "enum_init, 0>" + ], + [ + 95, + "const_as_immediate>" + ], + [ + 96, + "const_as_immediate>" + ] + ], + "user_func_names": [ + [ + 0, + "contracts::VotingContract::__wrapper__VotingContractImpl__vote" + ], + [ + 1, + "contracts::VotingContract::__wrapper__VotingContractImpl__get_votes" + ], + [ + 2, + "contracts::VotingContract::VotingContractImpl::vote" + ] + ] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x132bdf85fc8aa10ac3c22f02317f8f53d4b4f52235ed1eabb3a4cbbe08b5c41", + "function_idx": 0 + }, + { + "selector": "0x2d3b6c05bfaffaf4c2c46d2cbcb9061dd4aeeec09fc16da40ee1e40ba4dd555", + "function_idx": 1 + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + }, + "abi": [ + { + "type": "impl", + "name": "VotingContractImpl", + "interface_name": "contracts::IVotingContract" + }, + { + "type": "interface", + "name": "contracts::IVotingContract", + "items": [ + { + "type": "function", + "name": "vote", + "inputs": [ + { + "name": "vote", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_votes", + "inputs": [], + "outputs": [ + { + "type": "(core::felt252, core::felt252)" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "contracts::VotingContract::Event", + "kind": "enum", + "variants": [] + } + ] +} \ No newline at end of file From 525252a4889cdb8fd8d3a94c1c7a3a0350611709 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Thu, 11 Apr 2024 17:57:03 -0600 Subject: [PATCH 08/13] Move statistics to crates/sozo/ops/src and Use scarb print method --- bin/sozo/src/commands/build.rs | 41 +++++++++---------- bin/sozo/src/commands/options/mod.rs | 1 - crates/sozo/ops/src/lib.rs | 1 + .../sozo/ops/src}/statistics.rs | 15 +++---- 4 files changed, 26 insertions(+), 32 deletions(-) rename {bin/sozo/src/commands/options => crates/sozo/ops/src}/statistics.rs (94%) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index 507ab39ea3..b98ad428f6 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -4,9 +4,8 @@ use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; +use sozo_ops::statistics::{get_contract_statistics_for_dir, ContractStatistics}; -use super::options::statistics::{ContractStatistics, Stats}; -use crate::commands::options::statistics::get_contract_statistics_for_dir; #[derive(Args, Debug)] pub struct BuildArgs { #[arg(long)] @@ -21,8 +20,8 @@ pub struct BuildArgs { #[arg(help = "Output directory.", default_value = "bindings")] pub bindings_output: String, - #[command(flatten)] - pub stats: Stats, + #[arg(long, help = "Display statistics")] + pub stats: bool, } impl BuildArgs { @@ -41,11 +40,11 @@ impl BuildArgs { builtin_plugins.push(BuiltinPlugins::Unity); } - if self.stats.stats { + if self.stats { let contracts_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); for contract_stats in contracts_statistics { - print_stats(contract_stats); + print_stats(contract_stats, config); } } @@ -70,26 +69,23 @@ impl BuildArgs { } } -pub fn print_stats(contract_statistic: ContractStatistics) { - println!( - "---------------Contract Stats for {}---------------", - contract_statistic.contract_name - ); - - println!( - "- Contract bytecode size (Number of felts in the program): {}\n", - contract_statistic.number_felts, - ); - - println!("- Contract Class size: {} bytes\n", contract_statistic.file_size); +pub fn print_stats(contract_statistic: ContractStatistics, config: &Config) { + let contract_name = contract_statistic.contract_name; + let number_felts = contract_statistic.number_felts; + let file_size = contract_statistic.file_size; + config.ui().print(format!("---------------Contract Stats for {contract_name}---------------")); + config.ui().print(format!( + "- Contract bytecode size (Number of felts in the program): {number_felts}\n" + )); + config.ui().print(format!("- Contract Class size: {file_size} bytes\n")); } #[cfg(test)] mod tests { use dojo_test_utils::compiler::build_test_config; + use sozo_ops::statistics::ContractStatistics; use super::{print_stats, BuildArgs}; - use crate::commands::options::statistics::{ContractStatistics, Stats}; #[test] fn build_example_with_typescript_and_unity_bindings() { @@ -99,7 +95,7 @@ mod tests { bindings_output: "generated".to_string(), typescript: true, unity: true, - stats: Stats { stats: false }, + stats: false, }; let result = build_args.run(&config); assert!(result.is_ok()); @@ -108,12 +104,15 @@ mod tests { #[test] fn test_print_stats() { // Arrange + let config: scarb::core::Config = + build_test_config("../../examples/spawn-and-move/Scarb.toml").unwrap(); + let contract_statistic = ContractStatistics { contract_name: String::from("SampleContract"), number_felts: 100, file_size: 1024, }; // Act - print_stats(contract_statistic); + print_stats(contract_statistic, &config); } } diff --git a/bin/sozo/src/commands/options/mod.rs b/bin/sozo/src/commands/options/mod.rs index e997108381..0bd599bcc1 100644 --- a/bin/sozo/src/commands/options/mod.rs +++ b/bin/sozo/src/commands/options/mod.rs @@ -1,6 +1,5 @@ pub mod account; pub mod starknet; -pub mod statistics; pub mod transaction; pub mod world; diff --git a/crates/sozo/ops/src/lib.rs b/crates/sozo/ops/src/lib.rs index 3d1b69ce11..96e366bdf2 100644 --- a/crates/sozo/ops/src/lib.rs +++ b/crates/sozo/ops/src/lib.rs @@ -5,6 +5,7 @@ pub mod execute; pub mod migration; pub mod model; pub mod register; +pub mod statistics; pub mod utils; #[cfg(test)] diff --git a/bin/sozo/src/commands/options/statistics.rs b/crates/sozo/ops/src/statistics.rs similarity index 94% rename from bin/sozo/src/commands/options/statistics.rs rename to crates/sozo/ops/src/statistics.rs index 810cbdc364..5252d5b913 100644 --- a/bin/sozo/src/commands/options/statistics.rs +++ b/crates/sozo/ops/src/statistics.rs @@ -3,7 +3,6 @@ use std::path::PathBuf; use anyhow::Result; use camino::Utf8PathBuf; -use clap::Args; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; @@ -14,12 +13,6 @@ pub struct ContractStatistics { pub file_size: u64, } -#[derive(Debug, Args)] -pub struct Stats { - #[arg(long, help = "Display statistics")] - pub stats: bool, -} - pub fn read_sierra_json_program(file: &File) -> Result { let contract_artifact: SierraClass = serde_json::from_reader(file)?; let contract_artifact: FlattenedSierraClass = contract_artifact.flatten()?; @@ -93,9 +86,11 @@ mod tests { ContractStatistics, }; - const TEST_SIERRA_JSON_CONTRACT: &str = - "tests/test_data/sierra_compiled_contracts/contracts_test.contract_class.json"; - const TEST_SIERRA_FOLDER_CONTRACTS: &str = "tests/test_data/sierra_compiled_contracts/"; + const TEST_SIERRA_JSON_CONTRACT: &str = "../../../bin/sozo/tests/test_data/\ + sierra_compiled_contracts/contracts_test.\ + contract_class.json"; + const TEST_SIERRA_FOLDER_CONTRACTS: &str = + "../../../bin/sozo/tests/test_data/sierra_compiled_contracts/"; #[test] fn compute_contract_byte_code_size_returns_correct_size() { From 6ef19f2da21848e7e3f883f27f5e2ab80b9f95bf Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Fri, 12 Apr 2024 18:46:54 -0600 Subject: [PATCH 09/13] Applying all PR recomendations --- bin/sozo/src/commands/build.rs | 12 ++-- crates/sozo/ops/src/statistics.rs | 103 ++++++++++++++++-------------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index b98ad428f6..6a52feee04 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -20,7 +20,7 @@ pub struct BuildArgs { #[arg(help = "Output directory.", default_value = "bindings")] pub bindings_output: String, - #[arg(long, help = "Display statistics")] + #[arg(long, help = "Display statistics about the compiled contracts")] pub stats: bool, } @@ -41,7 +41,9 @@ impl BuildArgs { } if self.stats { - let contracts_statistics = get_contract_statistics_for_dir(&compile_info.target_dir); + let target_dir = &compile_info.target_dir; + let contracts_statistics = get_contract_statistics_for_dir(target_dir) + .expect(format!("Error getting contracts in dir {target_dir}").as_str()); for contract_stats in contracts_statistics { print_stats(contract_stats, config); @@ -74,10 +76,8 @@ pub fn print_stats(contract_statistic: ContractStatistics, config: &Config) { let number_felts = contract_statistic.number_felts; let file_size = contract_statistic.file_size; config.ui().print(format!("---------------Contract Stats for {contract_name}---------------")); - config.ui().print(format!( - "- Contract bytecode size (Number of felts in the program): {number_felts}\n" - )); - config.ui().print(format!("- Contract Class size: {file_size} bytes\n")); + config.ui().print(format!("Bytecode size: {number_felts}\n")); + config.ui().print(format!("Class size: {file_size} bytes\n")); } #[cfg(test)] diff --git a/crates/sozo/ops/src/statistics.rs b/crates/sozo/ops/src/statistics.rs index 5252d5b913..3a3693cee3 100644 --- a/crates/sozo/ops/src/statistics.rs +++ b/crates/sozo/ops/src/statistics.rs @@ -1,10 +1,10 @@ -use std::fs::{self, File}; -use std::path::PathBuf; - use anyhow::Result; use camino::Utf8PathBuf; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; +use std::fs::{self, File}; +use std::io; +use std::path::PathBuf; #[derive(Debug, PartialEq)] pub struct ContractStatistics { @@ -13,64 +13,67 @@ pub struct ContractStatistics { pub file_size: u64, } -pub fn read_sierra_json_program(file: &File) -> Result { +fn read_sierra_json_program(file: &File) -> Result { let contract_artifact: SierraClass = serde_json::from_reader(file)?; let contract_artifact: FlattenedSierraClass = contract_artifact.flatten()?; Ok(contract_artifact) } -pub fn compute_contract_byte_code_size(contract_artifact: FlattenedSierraClass) -> usize { - contract_artifact.sierra_program.len() +fn get_sierra_byte_code_size(contract_artifact: FlattenedSierraClass) -> u64 { + contract_artifact.sierra_program.len() as u64 } -pub fn get_file_size_in_bytes(file: File) -> u64 { - file.metadata().unwrap().len() +fn get_file_size(file: &File) -> Result { + file.metadata().map(|metadata| metadata.len()) } -pub fn get_contract_statistics_for_file( +fn get_contract_statistics_for_file( file_name: String, sierra_json_file: File, contract_artifact: FlattenedSierraClass, ) -> ContractStatistics { ContractStatistics { contract_name: file_name, - number_felts: compute_contract_byte_code_size(contract_artifact) as u64, - file_size: get_file_size_in_bytes(sierra_json_file), + number_felts: get_sierra_byte_code_size(contract_artifact), + file_size: get_file_size(&sierra_json_file) + .expect(format!("Error getting file size for file").as_str()), } } -pub fn get_contract_statistics_for_dir(target_directory: &Utf8PathBuf) -> Vec { +pub fn get_contract_statistics_for_dir( + target_directory: &Utf8PathBuf, +) -> Result> { let mut contract_statistics = Vec::new(); - let built_contract_paths: fs::ReadDir = fs::read_dir(target_directory.as_str()).unwrap(); + let target_directory = target_directory.as_str(); + let built_contract_paths: fs::ReadDir = fs::read_dir(target_directory) + .expect(format!("Error reading dir {target_directory}").as_str()); for sierra_json_path in built_contract_paths { - let sierra_json_path: PathBuf = sierra_json_path.unwrap().path(); - - let sierra_json_file: File = match File::open(&sierra_json_path) { - Ok(file) => file, - Err(_) => { - println!("Error opening Sierra JSON file: {}", sierra_json_path.display()); - continue; // Skip this file and proceed with the next one - } - }; + let sierra_json_path_buff: PathBuf = + sierra_json_path.expect("Error getting buffer for file").path(); - let contract_artifact: FlattenedSierraClass = - match read_sierra_json_program(&sierra_json_file) { - Ok(artifact) => artifact, - Err(_) => { - println!("Error reading Sierra JSON program: {}", sierra_json_path.display()); - continue; // Skip this file and proceed with the next one - } - }; + let file_name: String = sierra_json_path_buff + .file_stem() + .expect("Error getting file name") + .to_string_lossy() + .to_string(); + + let sierra_json_path_str = + sierra_json_path_buff.into_os_string().into_string().expect("String is expected"); + + let sierra_json_file: File = File::open(&sierra_json_path_str) + .expect(format!("Error opening Sierra JSON file: {sierra_json_path_str}").as_str()); + + let contract_artifact: FlattenedSierraClass = read_sierra_json_program(&sierra_json_file) + .expect(format!("Error reading Sierra JSON program: {sierra_json_path_str}").as_str()); - let filename = sierra_json_path.file_name().unwrap(); contract_statistics.push(get_contract_statistics_for_file( - filename.to_string_lossy().to_string(), + file_name, sierra_json_file, contract_artifact, )); } - contract_statistics + Ok(contract_statistics) } #[cfg(test)] @@ -81,9 +84,8 @@ mod tests { use camino::Utf8PathBuf; use super::{ - compute_contract_byte_code_size, get_contract_statistics_for_dir, - get_contract_statistics_for_file, get_file_size_in_bytes, read_sierra_json_program, - ContractStatistics, + get_contract_statistics_for_dir, get_contract_statistics_for_file, get_file_size, + get_sierra_byte_code_size, read_sierra_json_program, ContractStatistics, }; const TEST_SIERRA_JSON_CONTRACT: &str = "../../../bin/sozo/tests/test_data/\ @@ -93,16 +95,16 @@ mod tests { "../../../bin/sozo/tests/test_data/sierra_compiled_contracts/"; #[test] - fn compute_contract_byte_code_size_returns_correct_size() { + fn get_sierra_byte_code_size_returns_correct_size() { // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); let flattened_sierra_class = read_sierra_json_program(&sierra_json_file) .unwrap_or_else(|err| panic!("Failed to read JSON program: {}", err)); - let expected_number_of_felts: usize = 448; + let expected_number_of_felts: u64 = 448; // Act - let number_of_felts = compute_contract_byte_code_size(flattened_sierra_class); + let number_of_felts = get_sierra_byte_code_size(flattened_sierra_class); // Assert assert_eq!( @@ -119,10 +121,13 @@ mod tests { .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); let contract_artifact = read_sierra_json_program(&sierra_json_file) .unwrap_or_else(|err| panic!("Failed to read JSON program: {}", err)); - let filename = - Path::new(TEST_SIERRA_JSON_CONTRACT).file_name().unwrap().to_string_lossy().to_string(); + let filename = Path::new(TEST_SIERRA_JSON_CONTRACT) + .file_stem() + .expect("Error getting file name") + .to_string_lossy() + .to_string(); let expected_contract_statistics: ContractStatistics = ContractStatistics { - contract_name: String::from("contracts_test.contract_class.json"), + contract_name: String::from("contracts_test.contract_class"), number_felts: 448, file_size: 38384, }; @@ -142,21 +147,25 @@ mod tests { // Act let contract_statistics = - get_contract_statistics_for_dir(&path_full_of_built_sierra_contracts); + get_contract_statistics_for_dir(&path_full_of_built_sierra_contracts).expect( + format!("Error getting contracts in dir {path_full_of_built_sierra_contracts}") + .as_str(), + ); // Assert assert_eq!(contract_statistics.len(), 1, "Mismatch number of contract statistics"); } #[test] - fn get_file_size_in_bytes_returns_correct_size() { + fn get_file_size_returns_correct_size() { // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) - .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); + .unwrap_or_else(|err| panic!("Failed to open test file: {}", err)); const EXPECTED_SIZE: u64 = 38384; // Act - let file_size = get_file_size_in_bytes(sierra_json_file); + let file_size = get_file_size(&sierra_json_file) + .expect(format!("Error getting file size for test file").as_str()); // Assert assert_eq!(file_size, EXPECTED_SIZE, "File size mismatch"); @@ -166,7 +175,7 @@ mod tests { fn read_sierra_json_program_returns_ok_when_successful() { // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) - .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); + .unwrap_or_else(|err| panic!("Failed to open test file: {}", err)); // Act let result = read_sierra_json_program(&sierra_json_file); From 5c263e4b4ced1f9a27169d65768a5cffdefd6921 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Fri, 12 Apr 2024 21:43:20 -0600 Subject: [PATCH 10/13] Create table to output stats for contracts --- bin/sozo/Cargo.toml | 1 + bin/sozo/src/commands/build.rs | 99 ++++++++++++++++++++++++------- crates/sozo/ops/src/statistics.rs | 7 ++- 3 files changed, 81 insertions(+), 26 deletions(-) diff --git a/bin/sozo/Cargo.toml b/bin/sozo/Cargo.toml index 254734d9e3..cb3d0f0def 100644 --- a/bin/sozo/Cargo.toml +++ b/bin/sozo/Cargo.toml @@ -6,6 +6,7 @@ version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +prettytable-rs = "0.10.0" anyhow.workspace = true async-trait.workspace = true cairo-lang-compiler.workspace = true diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index 6a52feee04..7bc24b6dff 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -2,6 +2,7 @@ use anyhow::Result; use clap::Args; use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; +use prettytable::{format, Cell, Row, Table}; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; use sozo_ops::statistics::{get_contract_statistics_for_dir, ContractStatistics}; @@ -42,12 +43,11 @@ impl BuildArgs { if self.stats { let target_dir = &compile_info.target_dir; - let contracts_statistics = get_contract_statistics_for_dir(target_dir) - .expect(format!("Error getting contracts in dir {target_dir}").as_str()); - - for contract_stats in contracts_statistics { - print_stats(contract_stats, config); - } + let contracts_statistics: Vec = + get_contract_statistics_for_dir(target_dir) + .expect(format!("Error getting contracts in dir {target_dir}").as_str()); + let table = create_stats_table(contracts_statistics); + table.printstd() } // Custom plugins are always empty for now. @@ -71,21 +71,39 @@ impl BuildArgs { } } -pub fn print_stats(contract_statistic: ContractStatistics, config: &Config) { - let contract_name = contract_statistic.contract_name; - let number_felts = contract_statistic.number_felts; - let file_size = contract_statistic.file_size; - config.ui().print(format!("---------------Contract Stats for {contract_name}---------------")); - config.ui().print(format!("Bytecode size: {number_felts}\n")); - config.ui().print(format!("Class size: {file_size} bytes\n")); +fn create_stats_table(contracts_statistics: Vec) -> Table { + let mut table = Table::new(); + + // Add table headers + table.add_row(Row::new(vec![ + Cell::new_align("Contract", format::Alignment::CENTER), + Cell::new_align("Bytecode size (felts)", format::Alignment::CENTER), + Cell::new_align("Class size (bytes)", format::Alignment::CENTER), + ])); + + for contract_stats in contracts_statistics { + // Add table rows + let contract_name = contract_stats.contract_name; + let number_felts = contract_stats.number_felts; + let file_size = contract_stats.file_size; + + table.add_row(Row::new(vec![ + Cell::new_align(&contract_name, format::Alignment::LEFT), + Cell::new_align(format!("{}", number_felts).as_str(), format::Alignment::RIGHT), + Cell::new_align(format!("{}", file_size).as_str(), format::Alignment::RIGHT), + ])); + } + + table } #[cfg(test)] mod tests { use dojo_test_utils::compiler::build_test_config; + use prettytable::{format, Cell, Row, Table}; use sozo_ops::statistics::ContractStatistics; - use super::{print_stats, BuildArgs}; + use super::{create_stats_table, BuildArgs}; #[test] fn build_example_with_typescript_and_unity_bindings() { @@ -102,17 +120,52 @@ mod tests { } #[test] - fn test_print_stats() { + fn test_create_stats_table() { // Arrange - let config: scarb::core::Config = - build_test_config("../../examples/spawn-and-move/Scarb.toml").unwrap(); + let contracts_statistics = vec![ + ContractStatistics { + contract_name: "Test1".to_string(), + number_felts: 33, + file_size: 33, + }, + ContractStatistics { + contract_name: "Test2".to_string(), + number_felts: 43, + file_size: 24, + }, + ContractStatistics { + contract_name: "Test3".to_string(), + number_felts: 36, + file_size: 12, + }, + ]; + + let mut expected_table = Table::new(); + expected_table.add_row(Row::new(vec![ + Cell::new_align("Contract", format::Alignment::CENTER), + Cell::new_align("Bytecode size (felts)", format::Alignment::CENTER), + Cell::new_align("Class size (bytes)", format::Alignment::CENTER), + ])); + expected_table.add_row(Row::new(vec![ + Cell::new_align("Test1", format::Alignment::LEFT), + Cell::new_align(format!("{}", 33).as_str(), format::Alignment::RIGHT), + Cell::new_align(format!("{}", 33).as_str(), format::Alignment::RIGHT), + ])); + expected_table.add_row(Row::new(vec![ + Cell::new_align("Test2", format::Alignment::LEFT), + Cell::new_align(format!("{}", 43).as_str(), format::Alignment::RIGHT), + Cell::new_align(format!("{}", 24).as_str(), format::Alignment::RIGHT), + ])); + expected_table.add_row(Row::new(vec![ + Cell::new_align("Test3", format::Alignment::LEFT), + Cell::new_align(format!("{}", 36).as_str(), format::Alignment::RIGHT), + Cell::new_align(format!("{}", 12).as_str(), format::Alignment::RIGHT), + ])); - let contract_statistic = ContractStatistics { - contract_name: String::from("SampleContract"), - number_felts: 100, - file_size: 1024, - }; // Act - print_stats(contract_statistic, &config); + let table = create_stats_table(contracts_statistics); + + // Assert + assert_eq!(table, expected_table, "Tables mismatch") } } diff --git a/crates/sozo/ops/src/statistics.rs b/crates/sozo/ops/src/statistics.rs index 3a3693cee3..79a74a1043 100644 --- a/crates/sozo/ops/src/statistics.rs +++ b/crates/sozo/ops/src/statistics.rs @@ -1,10 +1,11 @@ +use std::fs::{self, File}; +use std::io; +use std::path::PathBuf; + use anyhow::Result; use camino::Utf8PathBuf; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; -use std::fs::{self, File}; -use std::io; -use std::path::PathBuf; #[derive(Debug, PartialEq)] pub struct ContractStatistics { From e1472d42930023bef728628990917ce66ee267c6 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 15 Apr 2024 12:16:17 -0600 Subject: [PATCH 11/13] Apply Code review recommendations in error handling and style nits --- Cargo.lock | 44 +- bin/sozo/src/commands/build.rs | 6 +- .../compiled_contracts/test_contract.json | 1 + .../contracts_test.contract_class.json | 1113 ----------------- crates/sozo/ops/src/statistics.rs | 85 +- 5 files changed, 87 insertions(+), 1162 deletions(-) create mode 120000 bin/sozo/tests/test_data/compiled_contracts/test_contract.json delete mode 100644 bin/sozo/tests/test_data/sierra_compiled_contracts/contracts_test.contract_class.json diff --git a/Cargo.lock b/Cargo.lock index aff69d7463..4e41736e2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2853,7 +2853,7 @@ version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ - "encode_unicode", + "encode_unicode 0.3.6", "lazy_static", "libc", "unicode-width", @@ -3127,6 +3127,27 @@ dependencies = [ "typenum", ] +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "ctor" version = "0.2.6" @@ -3880,6 +3901,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -9149,6 +9176,20 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "csv", + "encode_unicode 1.0.0", + "is-terminal", + "lazy_static", + "term", + "unicode-width", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -11088,6 +11129,7 @@ dependencies = [ "katana-runner", "notify", "notify-debouncer-mini", + "prettytable-rs", "scarb", "scarb-ui", "semver 1.0.22", diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index 7bc24b6dff..949b9af02f 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -1,7 +1,8 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use clap::Args; use dojo_bindgen::{BuiltinPlugins, PluginManager}; use dojo_lang::scarb_internal::compile_workspace; +use prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE; use prettytable::{format, Cell, Row, Table}; use scarb::core::{Config, TargetKind}; use scarb::ops::CompileOpts; @@ -45,7 +46,7 @@ impl BuildArgs { let target_dir = &compile_info.target_dir; let contracts_statistics: Vec = get_contract_statistics_for_dir(target_dir) - .expect(format!("Error getting contracts in dir {target_dir}").as_str()); + .context(format!("Error getting contracts stats"))?; let table = create_stats_table(contracts_statistics); table.printstd() } @@ -73,6 +74,7 @@ impl BuildArgs { fn create_stats_table(contracts_statistics: Vec) -> Table { let mut table = Table::new(); + table.set_format(*FORMAT_NO_LINESEP_WITH_TITLE); // Add table headers table.add_row(Row::new(vec![ diff --git a/bin/sozo/tests/test_data/compiled_contracts/test_contract.json b/bin/sozo/tests/test_data/compiled_contracts/test_contract.json new file mode 120000 index 0000000000..0bd6503ea2 --- /dev/null +++ b/bin/sozo/tests/test_data/compiled_contracts/test_contract.json @@ -0,0 +1 @@ +../../../../../crates/katana/primitives/contracts/compiled/cairo1_contract.json \ No newline at end of file diff --git a/bin/sozo/tests/test_data/sierra_compiled_contracts/contracts_test.contract_class.json b/bin/sozo/tests/test_data/sierra_compiled_contracts/contracts_test.contract_class.json deleted file mode 100644 index 13c5e7473f..0000000000 --- a/bin/sozo/tests/test_data/sierra_compiled_contracts/contracts_test.contract_class.json +++ /dev/null @@ -1,1113 +0,0 @@ -{ - "sierra_program": [ - "0x1", - "0x5", - "0x0", - "0x2", - "0x6", - "0x3", - "0x10a", - "0xf6", - "0x31", - "0x52616e6765436865636b", - "0x800000000000000100000000000000000000000000000000", - "0x436f6e7374", - "0x800000000000000000000000000000000000000000000002", - "0x1", - "0x9", - "0x2", - "0x766f74652063616e206f6e6c7920626520302f31", - "0x796f75206861766520616c726561647920766f746564", - "0x537472756374", - "0x800000000000000f00000000000000000000000000000001", - "0x0", - "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", - "0x456e756d", - "0x800000000000000700000000000000000000000000000003", - "0x3288d594b9a45d15bb2fcb7903f06cdb06b27f0ba88186ec4cfaa98307cb972", - "0x3", - "0xff1ffe08664adc45b814470c2bbab66e733624315d42e02a308cb838045f09", - "0x436f6e747261637441646472657373", - "0x800000000000000700000000000000000000000000000000", - "0x426f78", - "0x800000000000000700000000000000000000000000000001", - "0x12", - "0x14", - "0x66656c74323532", - "0x75313238", - "0x4172726179", - "0x800000000000000300000000000000000000000000000001", - "0x536e617073686f74", - "0xb", - "0x800000000000000700000000000000000000000000000002", - "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", - "0xc", - "0x15", - "0xe", - "0x1597b831feeb60c71f259624b79cf66995ea4f7e383403583674ab9c33b9cec", - "0xf", - "0x753332", - "0x80000000000000070000000000000000000000000000000e", - "0x348a62b7a38c0673e61e888d83a3ac1bf334ee7361a8514593d3d9532ed8b39", - "0x6", - "0xa", - "0xd", - "0x10", - "0x11", - "0x753634", - "0x800000000000000700000000000000000000000000000004", - "0x3808c701a5d13e100ab11b6c02f91f752ecae7e420d21b56c90ec0a475cc7e5", - "0x13", - "0x3342418ef16b3e2799b906b1e4e89dbb9b111332dd44f72458ce44f9895b508", - "0x800000000000000700000000000000000000000000000006", - "0x7d4d99e9ed8d285b5c61b493cedb63976bc3d9da867933d829f49ce838b5e7", - "0x8", - "0x7", - "0x16", - "0x4e6f6e5a65726f", - "0x53746f7261676541646472657373", - "0x53746f726167654261736541646472657373", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x4f7574206f6620676173", - "0x23b303364af8869c11625b6e258d6cc73f7fd3a4c3241e6fcc7aa62d7ebed66", - "0x886b8e7d947b37ccc7456de8ae2bccd8e362bc491b18c57571658245ffa914", - "0x3930ed7c9d3fcba01658f637f33fc53bf6b3e46e69f9e88525d760163abef3f", - "0x800000000000000f00000000000000000000000000000004", - "0x6ef897e9d8aceeb4a0d8bfdd21913eb84f93570d806717e6891805f20de808", - "0x21", - "0x22", - "0x23", - "0x800000000000000f00000000000000000000000000000003", - "0x24", - "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", - "0x800000000000000300000000000000000000000000000003", - "0x26", - "0x1ed07d901d6bb0038aaf2cf739e18b60db4655b11916d45285dcf9f41bd836", - "0x25", - "0x27", - "0x4275696c74696e436f737473", - "0x53797374656d", - "0x506564657273656e", - "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", - "0x20", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", - "0x4761734275696c74696e", - "0x61", - "0x7265766f6b655f61705f747261636b696e67", - "0x77697468647261775f676173", - "0x6272616e63685f616c69676e", - "0x7374727563745f6465636f6e737472756374", - "0x656e61626c655f61705f747261636b696e67", - "0x73746f72655f74656d70", - "0x61727261795f736e617073686f745f706f705f66726f6e74", - "0x756e626f78", - "0x72656e616d65", - "0x656e756d5f696e6974", - "0x2e", - "0x6a756d70", - "0x7374727563745f636f6e737472756374", - "0x656e756d5f6d61746368", - "0x64697361626c655f61705f747261636b696e67", - "0x64726f70", - "0x2f", - "0x61727261795f6e6577", - "0x636f6e73745f61735f696d6d656469617465", - "0x2d", - "0x61727261795f617070656e64", - "0x2c", - "0x2b", - "0x30", - "0x2a", - "0x6765745f6275696c74696e5f636f737473", - "0x29", - "0x77697468647261775f6761735f616c6c", - "0x66756e6374696f6e5f63616c6c", - "0x28", - "0x736e617073686f745f74616b65", - "0x1f", - "0x1e", - "0x73746f726167655f626173655f616464726573735f636f6e7374", - "0x286b0ba0cc51d6de16db5986d51fb912216629a146e2e12e67669af9b222dc9", - "0x73746f726167655f616464726573735f66726f6d5f62617365", - "0x1b", - "0x1c", - "0x73746f726167655f726561645f73797363616c6c", - "0x3b9050ac7bff930e1cf92e2ce5efc82c4df10fc1f75c5e1f465cd8d56d389b3", - "0x1a", - "0x647570", - "0x66656c743235325f69735f7a65726f", - "0x19", - "0x18", - "0x66656c743235325f737562", - "0x6765745f657865637574696f6e5f696e666f5f76325f73797363616c6c", - "0x17", - "0x636f6e74726163745f616464726573735f746f5f66656c74323532", - "0x5", - "0x706564657273656e", - "0xad292db4ff05a993c318438c1b6c8a8303266af2da151aa28ccece6726f1f1", - "0x4", - "0x626f6f6c5f6e6f745f696d706c", - "0x66656c743235325f616464", - "0x73746f726167655f77726974655f73797363616c6c", - "0x626f6f6c5f746f5f66656c74323532", - "0x1f6", - "0xffffffffffffffff", - "0x70", - "0x5f", - "0x1d", - "0x50", - "0x48", - "0x32", - "0x33", - "0x34", - "0x35", - "0x36", - "0x37", - "0x38", - "0x39", - "0x3a", - "0x3b", - "0x3c", - "0x3d", - "0x3e", - "0x3f", - "0x40", - "0x41", - "0x42", - "0x43", - "0x44", - "0x45", - "0x46", - "0x47", - "0xe2", - "0x94", - "0xd5", - "0xc8", - "0xc2", - "0xcc", - "0x49", - "0xf4", - "0xfc", - "0x1e5", - "0x1d9", - "0x4a", - "0x4b", - "0x4c", - "0x4d", - "0x4e", - "0x4f", - "0x1cc", - "0x11e", - "0x51", - "0x123", - "0x52", - "0x53", - "0x54", - "0x1ba", - "0x15a", - "0x14e", - "0x55", - "0x56", - "0x142", - "0x195", - "0x57", - "0x58", - "0x59", - "0x18f", - "0x183", - "0x5a", - "0x5b", - "0x5c", - "0x5d", - "0x5e", - "0x177", - "0x60", - "0x62", - "0x63", - "0x64", - "0x193", - "0x65", - "0x66", - "0x67", - "0x68", - "0x69", - "0x6a", - "0x6b", - "0x6c", - "0x6d", - "0x6e", - "0x6f", - "0x71", - "0x72", - "0x73", - "0x74", - "0x75", - "0x76", - "0x77", - "0x1af", - "0x78", - "0x79", - "0x7a", - "0x7b", - "0x7c", - "0x7d", - "0x7e", - "0x7f", - "0x80", - "0x81", - "0x82", - "0x83", - "0x84", - "0x85", - "0x86", - "0x87", - "0x88", - "0x89", - "0x8a", - "0x8b", - "0x8c", - "0x8d", - "0x8e", - "0x8f", - "0x90", - "0x91", - "0x92", - "0xf0", - "0x1232", - "0x440a1102840180f07034180b050240e06028100608038180a04018080200", - "0x142c1d03014381b0a06828190c0142c150b8142c150a04c2407030140803", - "0xa01827050504c2502890181f0508c0a160e8880a1c0d8840a200607c141e", - "0xb85605168145a05158145405160140c05030140c05158145405148140c05", - "0xd40a34060cc142a028c40a06028c8182f050a40a31028c40a30060bc1414", - "0x141a0c078280c050b0e00a070301408031b8142c15030145205148146c05", - "0x7c143c038180a04018ec0e060281006141d050720c038b40a04018180a06", - "0x28880521814840520830800a1f830160a1f030160a1e830160a158141a0c", - "0x1300a4b029281848070780a490283418480511c180b050440a46028341845", - "0x140c05298301e0e2901c0c050200c980528814a00c24038044f01138284d", - "0x140a5c060140a5b0616856050296418580615c18562a808a806028582a11", - "0x14c40c309800a052d8840a052d8300e600281cbe0602814bc0602814ba06", - "0x19c0c0502994cc05029944205029941864300140a630281cc0050397c2205", - "0x1ac0a072f9300a05311240a05310180a05350180a052d9a40a05340180a05", - "0x1881871380140a5b061bcd6050296cdc050296cda050296cd8050296c0a07", - "0x12c0a05329cc0a053181c2205391180a05311100a053110c0a05311080a05", - "0x194ea05029a01807358140e5f288140a62158140a620f0140a650f0140a74", - "0x14b62d02814b67a02814d00c3c9e00e053b8ac0a05329d80a05340440a05", - "0x140a5b3f0140a593f0140a653f0140a743f0140a623e81c0a77061f0f605", - "0xdc0a052ea140a052d831080c41a080a05342040a0532831000602814fe1e", - "0x1a01886148140a7f148140a5b148140a651b0140a651a8140a651b8140a59", - "0x14c60c458300e8a0281cbe8a02814b60503a280a072f831120c4421c0a05", - "0x140a5e368140a5e398140a5b0281ce6050397c8c0502994188d062311405", - "0x2400a0c060311e0502814d00702814d00c039cc0a072f92c0a05310311c6e", - "0x2400a8a02844180c480141807060d46c07488a50e074801c0e0503814180c", - "0x14461e1501d200703014520c438152005438150e0c062400a0c450300c05", - "0x8c0a060608c0a90028ac0a35060ac0a90028780a360603120050601c1821", - "0x30183102830420c168152005128143c0c16015200515014540c128152005", - "0x15200510814540c1881520050b814460c0b8152005060ac180c480141807", - "0x301890028300e0c11015241802a400e2d02894182d02a400a3102878182c", - "0xdc0a2d060312005060b0180c480141807062080a73428dc0e90038b00a29", - "0x30440c40815200506060180c48014300518830189002a140a17060312005", - "0x15200506208187a02a400a7e4081d0a0c3f01520053f0146e0c3f0152005", - "0x3018054801418053d030ec054801526053f031260548014f47b03a04187b", - "0x1d80a76060440a90028440a93060a40a90028a40a7b0621c0a9002a1c0a87", - "0x2080a2d060312005060b0180c480141807061d82229438310e053b0152005", - "0x1d20073a8a50e1121030ea0548014ea0528830ea05480141875060312005", - "0x309605480141844061180a9002830860c062400a0c03830884303a508451", - "0x14f60c288152005288150e0c2601520052492c8c11258309205480141846", - "0x2400a18028dc181102a400a1102a4c180c02a400a0c029e8184202a400a42", - "0x1a40a90039ac0a4c061acd86e381cd0e9002860981106108a229248303005", - "0x1980a70061980a9002830300c062400a69029cc180c480141807061800a95", - "0x1520054b014d60c4b015200500014d80c062400a6d029b818003681d2005", - "0x1ec187302a400a7302a1c186e02a400a6e029e8189802a400a97029a41897", - "0x1c0e66e4381530054801530053b030d80548014d80549830e00548014e005", - "0x150e0c37015200537014f40c4c815200530014fc0c062400a0c03831306c", - "0x2400a99029d8186c02a400a6c02a4c187002a400a70029ec187302a400a73", - "0x2400a0c0c0301890028600a310603120050601c1899361c0e66e438153205", - "0x31380548015369a03a14189b02a400a9b028dc189b02a400a0c300313405", - "0x300a7a0627c0a9002a780a7e062780a9002a713a07408313a05480141882", - "0x15200508815260c22015200522014f60c218152005218150e0c060152005", - "0x2400a0c160301890028300e0c4f84488430621c0a9f02a400a9f029d81811", - "0x2400a0c368314005480141818060312005160145a0c062400a2202998180c", - "0x314605480141882062880a9002a8540074283142054801542051b8314205", - "0x150e0c06015200506014f40c52815200552014fc0c5201520055128c0e81", - "0x2400aa5029d8181102a400a1102a4c182902a400a29029ec188702a400a87", - "0x2400a0c0c030189002a280a000603120050601c18a5088a50e0c438154a05", - "0x315005480154ea603a1418a702a400aa7028dc18a702a400a0c300314c05", - "0x300a7a062ac0a9002aa80a7e062a80a9002aa15207408315205480141882", - "0x15200508815260c1a81520051a814f60c1b01520051b0150e0c060152005", - "0x14180702830189002830180c558446a360621c0aab02a400aab029d81811", - "0x2280a87060d40a90028440a110603120050601c18361481d58874501d2007", - "0x140c05168301890028300e0c0f0155a2a0301d20071a814520c450152005", - "0xac0a37060ac0a9002830440c10815200506060180c4801454050b8301890", - "0x2400a231281d020c12815200506208182302a400a2b1081d0a0c158152005", - "0x310e05480150e053d8311405480151405438305a054801458053f0305805", - "0x3120050601c182d03a1d148a028b40a90028b40a760601c0a900281c0a93", - "0x21d1411210302e05480142e05288302e054801418750603120050f0145a0c", - "0x2140a97062140a90028312c0c062400a0c038306e2203ab8303103a400e17", - "0x268188102a400a8102a64180c48014188a062040a9002831300c410152005", - "0x1ecf47e08a400e824081c308a4d8306205480146205438310405480150405", - "0x30840548014a2054b830a20548014189c0603120050601c18753b24c22af", - "0x1484054d03086054801486054c830fc0548014fc053d8308605480141898", - "0x12422b02591888114801c84433d1f9149b061ec0a90029ec0a37061080a90", - "0x14967b03a74187002a400a0c0c030189002830580c062400a0c03830e64c", - "0x1a40e90029ac0aa0060312005360153e0c359b00e90029b80a9e061b80a90", - "0x30da0548014cc7003a14186602a400a66028dc186602a400a69028d41860", - "0x14e00c4b0152005001b40e85060000a90028000a37060000a90029800a35", - "0x2400a99029ac189902a400a98029b0180c480152e0537031309703a400a96", - "0x3088054801488053d8306205480146205438313605480153405348313405", - "0x3120050601c189b23110628a02a6c0a9002a6c0a76061180a90029180a93", - "0x1cc0aa1062740a90029300a93062700a90029240a7b0603120053d814620c", - "0x15260c4e015200549814f60c062400a0c0383018b102830420c4f0152005", - "0x313e05480141882060312005060b0189e02a400a7502a84189d02a400a76", - "0x14f60c188152005188150e0c50815200550014fc0c5001520054f27c0e81", - "0x2853a9c18a280aa102a400aa1029d8189d02a400a9d02a4c189c02a400a9c", - "0x152005518146e0c5181520050618018a202a400a0c0c0301890028300e0c", - "0x314c054801548a503a0418a502a400a0c4103148054801546a203a1418a3", - "0x1c0a93060dc0a90028dc0a7b060880a90028880a870629c0a9002a980a7e", - "0x14000c062400a0c038314e071b889140553815200553814ec0c038152005", - "0x3152054801552051b8315205480141860062a00a9002830300c062400a11", - "0x14fc0c4a8152005552ac0e81062ac0a9002831040c55015200554aa00e85", - "0x2400a0702a4c183602a400a36029ec182902a400a2902a1c18b202a400a95", - "0x28c18294381d200543815440c5901c6c294501564054801564053b0300e05", - "0x301890028300e0c062d00a0c108301890028300e0c1b015660c4801c5205", - "0xd40c07530300c8703a400a8702a88183502a400a0c528301890028d80aa4", - "0x2400a0c038303c055a831200715015460c150152005150146e0c150152005", - "0x8c0aa80603120050601c182d1609422b6118ac42114801c220503a9c180c", - "0x15560c428dc441818a1d20050b815540c0b815200511815520c118152005", - "0x2dc180c480150a05188301890028dc0ab20603120050c0152a0c062400a31", - "0x1418ba062040a9002a080ab90620844074801444055c0304405480144405", - "0x14f6051b830f67a03a400a813f01c22bb061f80a90029f80a37061f80a90", - "0x15200506260187502a400a7602a5c18764981d20053d8300ebc061ec0a90", - "0x21c187a02a400a7a029e8185102a400a5102a64182102a400a21029ec1851", - "0x300e0c2492c8c115e910864208a400e75288ac428a4d8312605480152605", - "0x10c0a900290c0a93061080a90029080a7b061100a90029100a37060312005", - "0x1cc0a94061cc0a9002830560c062400a0c0383098055f031200722015460c", - "0x15480c062400a0c0383018c002830420c370152005380157e0c380152005", - "0x1b80a90029ac0abf061ac0a90029b00ac1061b00a9002830560c062400a4c", - "0x1980ac430015200734815860c348152005348157e0c34815200537015840c", - "0x1cda0551830da8703a400a8702a88180c48014c005330301890028300e0c", - "0x25c189602a400a0c4b030189002a1c0a310603120050601c180002b141890", - "0x2400a9702a68189802a400a9802a64189802a400a0c4c0312e05480152c05", - "0x301890028300e0c4f27538116326d349908a400e974c10c848a4d8312e05", - "0x2400a9b028dc18a102a400a0c528314005480153e054b8313e05480141896", - "0x3132054801532053d8314605480141898062880a9002a853607638313605", - "0x2650ec8062880a9002a880a37062800a9002a800a9a0628c0a9002a8c0a99", - "0x15200552014f60c062400a0c0383150a75304592a55201d200751281469a", - "0x2400a8a02b2c180c4801418070603194050608418aa02a400aa502a4c18a9", - "0x15980c4a8152005542ac0e81062ac0a9002831040c062400a2202ac8180c", - "0x2400a7a029e818a602a400aa6029ec189302a400a9302a1c18b202a400a95", - "0x1c18b2539e94c93438156405480156405668314e05480154e0549830f405", - "0x20418b702a400a0c410301890028880ab206031200545015960c062400a0c", - "0x2700a7b0624c0a9002a4c0a87062e40a9002ae00acc062e00a9002a796e07", - "0x1520055c8159a0c4e81520054e815260c3d01520053d014f40c4e0152005", - "0x15200506294180c480140005520301890028300e0c5ca74f49c49a1c0ab9", - "0x159c0c4801d76055183176054801576051b831760548015748703a9818ba", - "0x2400a0c4c0317e054801528054b831280548014189c0603120050601c18bc", - "0x2400ebf6090c848a4d8317e05480157e054d03182054801582054c8318205", - "0x159a054b8319a0548014189c0603120050601c18cc65b2022cf63b0d8411", - "0x3480a9002b458e07638318e05480158e051b831a2054801418a5063400a90", - "0x3400a9a0634c0a9002b4c0a99063080a9002b080a7b0634c0a9002831300c", - "0x45aa926a01d200769341a6c36121d900c690152005690146e0c680152005", - "0x8418d902a400a9202a4c18d802a400ad4029ec180c4801418070635caad6", - "0x31040c062400a2202ac8180c480151405658301890028300e0c063680a0c", - "0x2400a9302a1c18dd02a400adc02b3018dc02a400ad76d81d020c6d8152005", - "0x30aa0548014aa0549830f40548014f4053d031ac0548015ac053d8312605", - "0x31200545015960c062400a0c03831ba553d359268702b740a9002b740acd", - "0x37c0acc0637c0a9002b31bc0740831bc0548014188206031200511015640c", - "0x1520053d014f40c64015200564014f60c498152005498150e0c700152005", - "0x300e0c7032cf4c849a1c0ae002a400ae002b3418cb02a400acb02a4c187a", - "0x31b20548014860549831b0054801484053d830189002af00aa4060312005", - "0x1418ba063840a90028880ab9062a80a9002b640ad1062a40a9002b600ad0", - "0x15c8051b831c8e303a400ae1711e822bb063880a9002b880a37063880a90", - "0x15200573015280c730152005060ac18917281d20057224c0ebc063900a90", - "0x15320c7501520050626018e902a400a9102a5c18e802a400ae702b4818e7", - "0x2400ae502a1c18e302a400ae3029e818e802a400ae8028dc18ea02a400aea", - "0x301890028300e0c783bddc1176bb1d6074801dd0e9752a9528764031ca05", - "0x3940a87063cc0a9002bc80ad4063c80a9002bc5140769831e20548014182b", - "0x15200576015260c71815200571814f40c75815200575814f60c728152005", - "0x151405658301890028300e0c79bb1c6eb72a1c0af302a400af302b3418ec", - "0x31ec0548015ea0566031ea0548015e0f403a0418f402a400a0c410301890", - "0x3bc0a930638c0a9002b8c0a7a063b80a9002bb80a7b063940a9002b940a87", - "0x198180c480141807063d9dee3773950e057b01520057b0159a0c778152005", - "0x30189002a1c0a3106031200511015640c062400a8a02b2c180c48014cc05", - "0x15f0f703a1418f802a400af8028dc18f802a400a0c49031ee05480141818", - "0x3f00a9002bec0acc063ec0a9002be5f40740831f405480141882063e40a90", - "0x15260c3d01520053d014f40c21015200521014f60c498152005498150e0c", - "0x301890028300e0c7e10cf44249a1c0afc02a400afc02b34184302a400a43", - "0x3f40a9002831040c062400a87028c4180c48014440559030189002a280acb", - "0x1ec189302a400a9302a1c18ff02a400afe02b3018fe02a400a497e81d020c", - "0x15fe0566830960548014960549830f40548014f4053d0308c05480148c05", - "0x21c0a3106031200545015960c062400a0c03831fe4b3d119268702bfc0a90", - "0x4080a9002c040acc064040a90028b60007408320005480141882060312005", - "0x15260c03815200503814f40c12815200512814f60c060152005060150e0c", - "0x301890028300e0c810b00e250621c0b0202a400b0202b34182c02a400a2c", - "0x40c0a9002830300c062400a87028c4180c480151405658301890028780aa4", - "0x31040c8281520058240c0e85064100a9002c100a37064100a9002831ac0c", - "0x2400a0c02a1c190802a400b0702b30190702a400b058301d020c830152005", - "0x302205480142205498300e05480140e053d0300a05480140a053d8301805", - "0x1acdc6d061b10e2b371b4186c43846101103814188702c200a9002c200acd", - "0x118dc6c3683052f50881c0a0c359b8da0c450acdc6d06228188a0881c0a0c", - "0x21287450440e05061ccdc6c368310e06" - ], - "sierra_program_debug_info": { - "type_names": [ - [ - 0, - "RangeCheck" - ], - [ - 1, - "Const" - ], - [ - 2, - "Const" - ], - [ - 3, - "Unit" - ], - [ - 4, - "core::bool" - ], - [ - 5, - "Const" - ], - [ - 6, - "ContractAddress" - ], - [ - 7, - "Box" - ], - [ - 8, - "Box" - ], - [ - 9, - "felt252" - ], - [ - 10, - "u128" - ], - [ - 11, - "Array" - ], - [ - 12, - "Snapshot>" - ], - [ - 13, - "core::array::Span::" - ], - [ - 14, - "Array" - ], - [ - 15, - "Snapshot>" - ], - [ - 16, - "core::array::Span::" - ], - [ - 17, - "u32" - ], - [ - 18, - "core::starknet::info::v2::TxInfo" - ], - [ - 19, - "u64" - ], - [ - 20, - "core::starknet::info::BlockInfo" - ], - [ - 21, - "core::starknet::info::v2::ResourceBounds" - ], - [ - 22, - "core::starknet::info::v2::ExecutionInfo" - ], - [ - 23, - "Box" - ], - [ - 24, - "Const" - ], - [ - 25, - "NonZero" - ], - [ - 26, - "Tuple" - ], - [ - 27, - "Const" - ], - [ - 28, - "StorageAddress" - ], - [ - 29, - "StorageBaseAddress" - ], - [ - 30, - "Const" - ], - [ - 31, - "Const" - ], - [ - 32, - "Tuple>" - ], - [ - 33, - "contracts::VotingContract::__member_module_yes_votes::ContractMemberState" - ], - [ - 34, - "contracts::VotingContract::__member_module_no_votes::ContractMemberState" - ], - [ - 35, - "contracts::VotingContract::__member_module_voters::ContractMemberState" - ], - [ - 36, - "contracts::VotingContract::ContractState" - ], - [ - 37, - "Tuple" - ], - [ - 38, - "core::panics::Panic" - ], - [ - 39, - "Tuple>" - ], - [ - 40, - "core::panics::PanicResult::<(contracts::VotingContract::ContractState, ())>" - ], - [ - 41, - "BuiltinCosts" - ], - [ - 42, - "System" - ], - [ - 43, - "Pedersen" - ], - [ - 44, - "core::panics::PanicResult::<(core::array::Span::,)>" - ], - [ - 45, - "Const" - ], - [ - 46, - "core::option::Option::" - ], - [ - 47, - "Box" - ], - [ - 48, - "GasBuiltin" - ] - ], - "libfunc_names": [ - [ - 0, - "revoke_ap_tracking" - ], - [ - 1, - "withdraw_gas" - ], - [ - 2, - "branch_align" - ], - [ - 3, - "struct_deconstruct>" - ], - [ - 4, - "enable_ap_tracking" - ], - [ - 5, - "store_temp" - ], - [ - 6, - "array_snapshot_pop_front" - ], - [ - 7, - "unbox" - ], - [ - 8, - "rename" - ], - [ - 9, - "enum_init, 0>" - ], - [ - 10, - "store_temp>>" - ], - [ - 11, - "store_temp>" - ], - [ - 12, - "jump" - ], - [ - 13, - "struct_construct" - ], - [ - 14, - "enum_init, 1>" - ], - [ - 15, - "enum_match>" - ], - [ - 16, - "disable_ap_tracking" - ], - [ - 17, - "drop>>" - ], - [ - 18, - "drop>" - ], - [ - 19, - "drop" - ], - [ - 20, - "array_new" - ], - [ - 21, - "const_as_immediate>" - ], - [ - 22, - "store_temp" - ], - [ - 23, - "array_append" - ], - [ - 24, - "struct_construct" - ], - [ - 25, - "struct_construct>>" - ], - [ - 26, - "enum_init,)>, 1>" - ], - [ - 27, - "store_temp" - ], - [ - 28, - "store_temp" - ], - [ - 29, - "store_temp" - ], - [ - 30, - "store_temp,)>>" - ], - [ - 31, - "get_builtin_costs" - ], - [ - 32, - "store_temp" - ], - [ - 33, - "withdraw_gas_all" - ], - [ - 34, - "struct_construct" - ], - [ - 35, - "struct_construct" - ], - [ - 36, - "struct_construct" - ], - [ - 37, - "struct_construct" - ], - [ - 38, - "function_call" - ], - [ - 39, - "enum_match>" - ], - [ - 40, - "drop>" - ], - [ - 41, - "snapshot_take>" - ], - [ - 42, - "drop>" - ], - [ - 43, - "struct_construct>" - ], - [ - 44, - "struct_construct>>" - ], - [ - 45, - "enum_init,)>, 0>" - ], - [ - 46, - "const_as_immediate>" - ], - [ - 47, - "drop" - ], - [ - 48, - "const_as_immediate>" - ], - [ - 49, - "drop>" - ], - [ - 50, - "storage_base_address_const<1142602927098787396562020832295408108705589548626984240874450201634165370313>" - ], - [ - 51, - "storage_address_from_base" - ], - [ - 52, - "const_as_immediate>" - ], - [ - 53, - "store_temp" - ], - [ - 54, - "store_temp" - ], - [ - 55, - "storage_read_syscall" - ], - [ - 56, - "storage_base_address_const<1683840052101120209483954731935227110542988872268356551521531283411842599347>" - ], - [ - 57, - "struct_construct>" - ], - [ - 58, - "snapshot_take>" - ], - [ - 59, - "drop>" - ], - [ - 60, - "struct_deconstruct>" - ], - [ - 61, - "store_temp>" - ], - [ - 62, - "dup" - ], - [ - 63, - "felt252_is_zero" - ], - [ - 64, - "drop>" - ], - [ - 65, - "const_as_immediate>" - ], - [ - 66, - "felt252_sub" - ], - [ - 67, - "get_execution_info_v2_syscall" - ], - [ - 68, - "store_temp>" - ], - [ - 69, - "unbox" - ], - [ - 70, - "struct_deconstruct" - ], - [ - 71, - "drop>" - ], - [ - 72, - "drop>" - ], - [ - 73, - "drop" - ], - [ - 74, - "store_temp" - ], - [ - 75, - "dup" - ], - [ - 76, - "contract_address_to_felt252" - ], - [ - 77, - "const_as_immediate>" - ], - [ - 78, - "pedersen" - ], - [ - 79, - "storage_base_address_from_felt252" - ], - [ - 80, - "enum_init" - ], - [ - 81, - "store_temp" - ], - [ - 82, - "enum_init" - ], - [ - 83, - "bool_not_impl" - ], - [ - 84, - "enum_match" - ], - [ - 85, - "felt252_add" - ], - [ - 86, - "storage_write_syscall" - ], - [ - 87, - "drop" - ], - [ - 88, - "enum_init, 1>" - ], - [ - 89, - "store_temp>" - ], - [ - 90, - "rename" - ], - [ - 91, - "rename" - ], - [ - 92, - "bool_to_felt252" - ], - [ - 93, - "struct_construct>" - ], - [ - 94, - "enum_init, 0>" - ], - [ - 95, - "const_as_immediate>" - ], - [ - 96, - "const_as_immediate>" - ] - ], - "user_func_names": [ - [ - 0, - "contracts::VotingContract::__wrapper__VotingContractImpl__vote" - ], - [ - 1, - "contracts::VotingContract::__wrapper__VotingContractImpl__get_votes" - ], - [ - 2, - "contracts::VotingContract::VotingContractImpl::vote" - ] - ] - }, - "contract_class_version": "0.1.0", - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0x132bdf85fc8aa10ac3c22f02317f8f53d4b4f52235ed1eabb3a4cbbe08b5c41", - "function_idx": 0 - }, - { - "selector": "0x2d3b6c05bfaffaf4c2c46d2cbcb9061dd4aeeec09fc16da40ee1e40ba4dd555", - "function_idx": 1 - } - ], - "L1_HANDLER": [], - "CONSTRUCTOR": [] - }, - "abi": [ - { - "type": "impl", - "name": "VotingContractImpl", - "interface_name": "contracts::IVotingContract" - }, - { - "type": "interface", - "name": "contracts::IVotingContract", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "vote", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_votes", - "inputs": [], - "outputs": [ - { - "type": "(core::felt252, core::felt252)" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "contracts::VotingContract::Event", - "kind": "enum", - "variants": [] - } - ] -} \ No newline at end of file diff --git a/crates/sozo/ops/src/statistics.rs b/crates/sozo/ops/src/statistics.rs index 79a74a1043..82c43ed04b 100644 --- a/crates/sozo/ops/src/statistics.rs +++ b/crates/sozo/ops/src/statistics.rs @@ -1,8 +1,8 @@ use std::fs::{self, File}; -use std::io; +use std::io::{self, BufReader}; use std::path::PathBuf; -use anyhow::Result; +use anyhow::{Context, Result}; use camino::Utf8PathBuf; use starknet::core::types::contract::SierraClass; use starknet::core::types::FlattenedSierraClass; @@ -15,7 +15,7 @@ pub struct ContractStatistics { } fn read_sierra_json_program(file: &File) -> Result { - let contract_artifact: SierraClass = serde_json::from_reader(file)?; + let contract_artifact: SierraClass = serde_json::from_reader(BufReader::new(file))?; let contract_artifact: FlattenedSierraClass = contract_artifact.flatten()?; Ok(contract_artifact) @@ -30,16 +30,13 @@ fn get_file_size(file: &File) -> Result { } fn get_contract_statistics_for_file( - file_name: String, + contract_name: String, sierra_json_file: File, contract_artifact: FlattenedSierraClass, -) -> ContractStatistics { - ContractStatistics { - contract_name: file_name, - number_felts: get_sierra_byte_code_size(contract_artifact), - file_size: get_file_size(&sierra_json_file) - .expect(format!("Error getting file size for file").as_str()), - } +) -> Result { + let file_size = get_file_size(&sierra_json_file).context(format!("Error getting file size"))?; + let number_felts = get_sierra_byte_code_size(contract_artifact); + Ok(ContractStatistics { file_size, contract_name, number_felts }) } pub fn get_contract_statistics_for_dir( @@ -47,32 +44,31 @@ pub fn get_contract_statistics_for_dir( ) -> Result> { let mut contract_statistics = Vec::new(); let target_directory = target_directory.as_str(); - let built_contract_paths: fs::ReadDir = fs::read_dir(target_directory) - .expect(format!("Error reading dir {target_directory}").as_str()); - for sierra_json_path in built_contract_paths { - let sierra_json_path_buff: PathBuf = - sierra_json_path.expect("Error getting buffer for file").path(); + let dir: fs::ReadDir = fs::read_dir(target_directory)?; + for entry in dir { + let path: PathBuf = entry?.path(); - let file_name: String = sierra_json_path_buff - .file_stem() - .expect("Error getting file name") - .to_string_lossy() - .to_string(); + if path.is_dir() { + continue; + } - let sierra_json_path_str = - sierra_json_path_buff.into_os_string().into_string().expect("String is expected"); + let contract_name: String = + path.file_stem().context("Error getting file name")?.to_string_lossy().to_string(); - let sierra_json_file: File = File::open(&sierra_json_path_str) - .expect(format!("Error opening Sierra JSON file: {sierra_json_path_str}").as_str()); + let sierra_json_file: File = + File::open(&path).context(format!("Error opening file: {}", path.to_string_lossy()))?; let contract_artifact: FlattenedSierraClass = read_sierra_json_program(&sierra_json_file) - .expect(format!("Error reading Sierra JSON program: {sierra_json_path_str}").as_str()); + .context(format!( + "Error parsing Sierra class artifact: {}", + path.to_string_lossy() + ))?; contract_statistics.push(get_contract_statistics_for_file( - file_name, + contract_name, sierra_json_file, contract_artifact, - )); + )?); } Ok(contract_statistics) } @@ -89,11 +85,10 @@ mod tests { get_sierra_byte_code_size, read_sierra_json_program, ContractStatistics, }; - const TEST_SIERRA_JSON_CONTRACT: &str = "../../../bin/sozo/tests/test_data/\ - sierra_compiled_contracts/contracts_test.\ - contract_class.json"; + const TEST_SIERRA_JSON_CONTRACT: &str = + "../../../bin/sozo/tests/test_data/compiled_contracts/test_contract.json"; const TEST_SIERRA_FOLDER_CONTRACTS: &str = - "../../../bin/sozo/tests/test_data/sierra_compiled_contracts/"; + "../../../bin/sozo/tests/test_data/compiled_contracts/"; #[test] fn get_sierra_byte_code_size_returns_correct_size() { @@ -102,16 +97,16 @@ mod tests { .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); let flattened_sierra_class = read_sierra_json_program(&sierra_json_file) .unwrap_or_else(|err| panic!("Failed to read JSON program: {}", err)); - let expected_number_of_felts: u64 = 448; + const EXPECTED_NUMBER_OF_FELTS: u64 = 2175; // Act let number_of_felts = get_sierra_byte_code_size(flattened_sierra_class); // Assert assert_eq!( - number_of_felts, expected_number_of_felts, + number_of_felts, EXPECTED_NUMBER_OF_FELTS, "Number of felts mismatch. Expected {}, got {}", - expected_number_of_felts, number_of_felts + EXPECTED_NUMBER_OF_FELTS, number_of_felts ); } @@ -128,14 +123,15 @@ mod tests { .to_string_lossy() .to_string(); let expected_contract_statistics: ContractStatistics = ContractStatistics { - contract_name: String::from("contracts_test.contract_class"), - number_felts: 448, - file_size: 38384, + contract_name: String::from("test_contract"), + number_felts: 2175, + file_size: 114925, }; // Act let statistics = - get_contract_statistics_for_file(filename.clone(), sierra_json_file, contract_artifact); + get_contract_statistics_for_file(filename.clone(), sierra_json_file, contract_artifact) + .expect("Error getting contract statistics for file"); // Assert assert_eq!(statistics, expected_contract_statistics); @@ -144,14 +140,11 @@ mod tests { #[test] fn get_contract_statistics_for_dir_returns_correct_statistics() { // Arrange - let path_full_of_built_sierra_contracts = Utf8PathBuf::from(TEST_SIERRA_FOLDER_CONTRACTS); + let target_dir = Utf8PathBuf::from(TEST_SIERRA_FOLDER_CONTRACTS); // Act - let contract_statistics = - get_contract_statistics_for_dir(&path_full_of_built_sierra_contracts).expect( - format!("Error getting contracts in dir {path_full_of_built_sierra_contracts}") - .as_str(), - ); + let contract_statistics = get_contract_statistics_for_dir(&target_dir) + .expect(format!("Error getting contracts in dir {target_dir}").as_str()); // Assert assert_eq!(contract_statistics.len(), 1, "Mismatch number of contract statistics"); @@ -162,7 +155,7 @@ mod tests { // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) .unwrap_or_else(|err| panic!("Failed to open test file: {}", err)); - const EXPECTED_SIZE: u64 = 38384; + const EXPECTED_SIZE: u64 = 114925; // Act let file_size = get_file_size(&sierra_json_file) From 211354941a58bf7cebb41bd9a5fd7d457b75f755 Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 15 Apr 2024 13:20:18 -0600 Subject: [PATCH 12/13] Fix unit test --- bin/sozo/src/commands/build.rs | 3 +++ bin/sozo/tests/test_data/compiled_contracts/test_contract.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index c24d8cb6e8..26fd8a7dc7 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -110,6 +110,7 @@ fn create_stats_table(contracts_statistics: Vec) -> Table { #[cfg(test)] mod tests { use dojo_test_utils::compiler::build_test_config; + use prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE; use prettytable::{format, Cell, Row, Table}; use sozo_ops::statistics::ContractStatistics; @@ -124,6 +125,7 @@ mod tests { typescript: true, unity: true, typescript_v2: true, + stats: true, }; let result = build_args.run(&config); assert!(result.is_ok()); @@ -151,6 +153,7 @@ mod tests { ]; let mut expected_table = Table::new(); + expected_table.set_format(*FORMAT_NO_LINESEP_WITH_TITLE); expected_table.add_row(Row::new(vec![ Cell::new_align("Contract", format::Alignment::CENTER), Cell::new_align("Bytecode size (felts)", format::Alignment::CENTER), diff --git a/bin/sozo/tests/test_data/compiled_contracts/test_contract.json b/bin/sozo/tests/test_data/compiled_contracts/test_contract.json index 0bd6503ea2..c7a135aa79 120000 --- a/bin/sozo/tests/test_data/compiled_contracts/test_contract.json +++ b/bin/sozo/tests/test_data/compiled_contracts/test_contract.json @@ -1 +1 @@ -../../../../../crates/katana/primitives/contracts/compiled/cairo1_contract.json \ No newline at end of file +../../../../../crates/katana/contracts/compiled/cairo1_contract.json \ No newline at end of file From 7e0f74205138336a6f123e385d7b575e60686e6b Mon Sep 17 00:00:00 2001 From: Fabricio Robles Date: Mon, 15 Apr 2024 18:22:44 -0600 Subject: [PATCH 13/13] - Delete Act Arrange Assert comments - Let compiler infer types --- bin/sozo/src/commands/build.rs | 11 +++++------ crates/sozo/ops/src/statistics.rs | 14 -------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/bin/sozo/src/commands/build.rs b/bin/sozo/src/commands/build.rs index 26fd8a7dc7..075268c40d 100644 --- a/bin/sozo/src/commands/build.rs +++ b/bin/sozo/src/commands/build.rs @@ -32,7 +32,7 @@ pub struct BuildArgs { impl BuildArgs { pub fn run(self, config: &Config) -> Result<()> { - let compile_info: dojo_lang::scarb_internal::CompileInfo = compile_workspace( + let compile_info = compile_workspace( config, CompileOpts { include_targets: vec![], exclude_targets: vec![TargetKind::TEST] }, )?; @@ -52,9 +52,8 @@ impl BuildArgs { if self.stats { let target_dir = &compile_info.target_dir; - let contracts_statistics: Vec = - get_contract_statistics_for_dir(target_dir) - .context(format!("Error getting contracts stats"))?; + let contracts_statistics = get_contract_statistics_for_dir(target_dir) + .context(format!("Error getting contracts stats"))?; let table = create_stats_table(contracts_statistics); table.printstd() } @@ -85,7 +84,7 @@ fn create_stats_table(contracts_statistics: Vec) -> Table { table.set_format(*FORMAT_NO_LINESEP_WITH_TITLE); // Add table headers - table.add_row(Row::new(vec![ + table.set_titles(Row::new(vec![ Cell::new_align("Contract", format::Alignment::CENTER), Cell::new_align("Bytecode size (felts)", format::Alignment::CENTER), Cell::new_align("Class size (bytes)", format::Alignment::CENTER), @@ -154,7 +153,7 @@ mod tests { let mut expected_table = Table::new(); expected_table.set_format(*FORMAT_NO_LINESEP_WITH_TITLE); - expected_table.add_row(Row::new(vec![ + expected_table.set_titles(Row::new(vec![ Cell::new_align("Contract", format::Alignment::CENTER), Cell::new_align("Bytecode size (felts)", format::Alignment::CENTER), Cell::new_align("Class size (bytes)", format::Alignment::CENTER), diff --git a/crates/sozo/ops/src/statistics.rs b/crates/sozo/ops/src/statistics.rs index 82c43ed04b..741cd61dee 100644 --- a/crates/sozo/ops/src/statistics.rs +++ b/crates/sozo/ops/src/statistics.rs @@ -92,17 +92,14 @@ mod tests { #[test] fn get_sierra_byte_code_size_returns_correct_size() { - // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); let flattened_sierra_class = read_sierra_json_program(&sierra_json_file) .unwrap_or_else(|err| panic!("Failed to read JSON program: {}", err)); const EXPECTED_NUMBER_OF_FELTS: u64 = 2175; - // Act let number_of_felts = get_sierra_byte_code_size(flattened_sierra_class); - // Assert assert_eq!( number_of_felts, EXPECTED_NUMBER_OF_FELTS, "Number of felts mismatch. Expected {}, got {}", @@ -112,7 +109,6 @@ mod tests { #[test] fn get_contract_statistics_for_file_returns_correct_statistics() { - // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) .unwrap_or_else(|err| panic!("Failed to open file: {}", err)); let contract_artifact = read_sierra_json_program(&sierra_json_file) @@ -128,40 +124,32 @@ mod tests { file_size: 114925, }; - // Act let statistics = get_contract_statistics_for_file(filename.clone(), sierra_json_file, contract_artifact) .expect("Error getting contract statistics for file"); - // Assert assert_eq!(statistics, expected_contract_statistics); } #[test] fn get_contract_statistics_for_dir_returns_correct_statistics() { - // Arrange let target_dir = Utf8PathBuf::from(TEST_SIERRA_FOLDER_CONTRACTS); - // Act let contract_statistics = get_contract_statistics_for_dir(&target_dir) .expect(format!("Error getting contracts in dir {target_dir}").as_str()); - // Assert assert_eq!(contract_statistics.len(), 1, "Mismatch number of contract statistics"); } #[test] fn get_file_size_returns_correct_size() { - // Arrange let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) .unwrap_or_else(|err| panic!("Failed to open test file: {}", err)); const EXPECTED_SIZE: u64 = 114925; - // Act let file_size = get_file_size(&sierra_json_file) .expect(format!("Error getting file size for test file").as_str()); - // Assert assert_eq!(file_size, EXPECTED_SIZE, "File size mismatch"); } @@ -171,10 +159,8 @@ mod tests { let sierra_json_file = File::open(TEST_SIERRA_JSON_CONTRACT) .unwrap_or_else(|err| panic!("Failed to open test file: {}", err)); - // Act let result = read_sierra_json_program(&sierra_json_file); - // Assert assert!(result.is_ok(), "Expected Ok result"); } }