diff --git a/.dockerignore b/.dockerignore index d5dc94b4..e5aa1378 100644 --- a/.dockerignore +++ b/.dockerignore @@ -30,3 +30,4 @@ tools/ hdp-cairo/ build/ *.pie +*.json diff --git a/.gitignore b/.gitignore index 8abfde8a..5a8bcc23 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ tools/ hdp-cairo/ build/ *.pie +*.json \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index c7d3fcd2..c892c22e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1061,9 +1061,9 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d9c31baeb6b52586b5adc88f01e90f86389d63d94363c562de5c79352e545b" +checksum = "6296d5748288d9fb97175d31aff9f68ea3f602456923895e512b078e9a2210a0" dependencies = [ "cairo-lang-utils", "indoc", @@ -1075,9 +1075,9 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc43246cc2e5afd5a028bcdd63876ac3f8b1f4fb3ff785daaa0f0fbb51c9d906" +checksum = "4f95f5c8f7ea75580d164b5304251022e3d47f43fc1c778a01381b55ca9f268c" dependencies = [ "cairo-lang-utils", "good_lp", @@ -1085,9 +1085,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07da3ca1434c62a7cc7cd77d2941ef47a1c23b37325781b59407b78d8c61d863" +checksum = "74a57492267a5a8891866b6e48cdefa508b5f05931a5f8eaf004b9de15b1ffd6" dependencies = [ "anyhow", "cairo-felt", @@ -1111,9 +1111,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122c9055eb609a511178e3dce577de061819fd4c4c6b7452804557f76ca43bbf" +checksum = "6fdbb4bd95477123653b9200bd4e9dceae95a914f6fe85b2bed83b223e36fb5a" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -1126,9 +1126,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf049d9aea65c6e38da219a3700c72f78795d11449d9adcec28047ef8d63bd23" +checksum = "882cb178f1b79aabf70acce1d87b08d569d8a4b0ce8b1d8f538a02cdb36789db" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -1141,9 +1141,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3c3be88c8562fbf93b0803c186e7282f6daad93576c07f61b04a591fde468f" +checksum = "3ac02c90be2630ae861db6af226090da92741020519768332dd2c07e24d94c75" dependencies = [ "assert_matches", "cairo-felt", @@ -1162,9 +1162,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38da6f98c6b16945c89d2ae351c82d636ed38d3e6eb02f7c8679e3e03a63988" +checksum = "d102b10989f9637b1c916dd950cbd1bd8bb1b6a7aaa1a3035390be0683b92d85" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -1172,9 +1172,9 @@ dependencies = [ [[package]] name = "cairo-lang-starknet-classes" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c64ae2bb00173e3a88760128bf72de356fa80eb19fa47602479063648b4003" +checksum = "8623b076ef3569e4262da5da270a84658b1ff242fe0c9624fbe432e7a937d101" dependencies = [ "cairo-felt", "cairo-lang-casm", @@ -1197,9 +1197,9 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf733a7cdc4166d0baf0ed8a98d9ada827daee6653b37d9326e334e53481c6d3" +checksum = "e6f98e8769412907ceb106c21c70907cc0c87ca0a2a44c82b6229a695a6f9b48" dependencies = [ "hashbrown 0.14.5", "indexmap 2.2.6", @@ -2184,6 +2184,7 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", + "starknet", "starknet-crypto", "tempfile", "thiserror", @@ -2204,6 +2205,7 @@ dependencies = [ "hdp-provider", "inquire", "serde_json", + "starknet", "tokio", "tracing", "tracing-subscriber", @@ -2259,6 +2261,7 @@ dependencies = [ "hdp-primitives", "serde", "serde_json", + "tracing", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1d0cb68d..56d0e257 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ rand = "0.8.4" regex = "1" starknet = "0.10.0" starknet-crypto = "0.6.1" -cairo-lang-starknet-classes = "2.6.3" +cairo-lang-starknet-classes = "2.6.4" futures = "0.3.30" lazy_static = "1.4.0" thiserror = "1.0" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 03227f64..8819bda1 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -26,6 +26,7 @@ tracing = { workspace = true } hdp-provider = { workspace = true } hdp-primitives = { workspace = true } serde_json = { workspace = true } +starknet = { workspace = true } clap = { version = "4.4.4", features = ["derive"] } dotenv = "0.15.0" tracing-subscriber = "0.3.0" diff --git a/cli/src/commands.rs b/cli/src/commands.rs index 1200cdb1..8a1c2e9c 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -48,23 +48,23 @@ pub enum HDPCliCommands { /// The chain id to fetch the datalake chain_id: Option, - /// Path to save output file after pre-process, this is the input file for processor + /// Path to save output file after pre-processing. /// /// This will trigger pre-processing step #[arg(short, long)] - cairo_input: Option, + preprocessor_output_file: Option, /// Path to save output file after process /// /// This will trigger processing(=pie generation) step - #[arg(short, long, requires("cairo_input"))] + #[arg(short, long, requires("pre_processor_output"))] output_file: Option, /// Path to save pie file /// /// This will trigger processing(=pie generation) step - #[arg(short, long, requires("cairo_input"))] - pie_file: Option, + #[arg(short, long, requires("pre_processor_output"))] + cairo_pie_file: Option, }, /// Decode batch computes and datalakes /// @@ -88,7 +88,8 @@ pub enum HDPCliCommands { datalake: Bytes, }, /// Run from encoded compute and datalake. Usefull for request batch tasks. - Run { + #[command(arg_required_else_help = true)] + RunDatalake { /// Batched computes bytes #[arg(value_parser = parse_bytes)] tasks: Option, @@ -100,23 +101,86 @@ pub enum HDPCliCommands { /// The chain id to fetch the data chain_id: Option, - /// Path to save output file after pre-process, this is the input file for processor + /// Path to save output file after pre-processing. + /// + /// This will trigger pre-processing step + #[arg(short, long)] + preprocessor_output_file: Option, + + /// Path to save output file after process + /// + /// This will trigger processing(=pie generation) step + #[arg(short, long, requires("pre_processor_output"))] + output_file: Option, + + /// Path to save pie file + /// + /// This will trigger processing(=pie generation) step + #[arg(short, long, requires("pre_processor_output"))] + cairo_pie_file: Option, + }, + + /// Run module with either class hash deployed on starknet or local class path + #[command(arg_required_else_help = true)] + RunModule { + /// Input field elements for the module contract. + /// The input field elements should be separated by comma. + /// + /// e.g. "0x1234,0xabcd" + #[arg(required = true, use_value_delimiter = true)] + module_inputs: Vec, + + /// Class hash of the module that deployed on starknet. + /// This will trigger fetching the class from the starknet. + /// + /// (Note: either class_hash or local_class_path should be provided) + #[arg(long, group = "class_source")] + class_hash: Option, + + /// Local path of the contract class file. + /// Make sure to have structure match with [CasmContractClass](https://github.com/starkware-libs/cairo/blob/53f7a0d26d5c8a99a8ad6ba07207a762678f2931/crates/cairo-lang-starknet-classes/src/casm_contract_class.rs) + /// + /// (Note: either class_hash or local_class_path should be provided) + #[arg(long, group = "class_source")] + local_class_path: Option, + + /// The RPC URL to fetch the data. + /// + /// Can be overwritten by `RPC_URL` environment variable. + #[arg(long)] + rpc_url: Option, + + /// The chain id to fetch the data. + /// + /// Can be overwritten by `CHAIN_ID` environment variable + #[arg(long)] + chain_id: Option, + + /// Module registry starknet rpc url, This is used to fetch the class from the module registry + /// + /// (Note: This is only used when the class is provided by `class_hash`) + /// + /// Can be overwritten by `MODULE_REGISTRY_RPC_URL` environment variable + #[arg(long, requires("class_hash"))] + module_registry_rpc_url: Option, + + /// Path to save output file after pre-processing. /// /// This will trigger pre-processing step #[arg(short, long)] - cairo_input: Option, + preprocessor_output_file: Option, /// Path to save output file after process /// /// This will trigger processing(=pie generation) step - #[arg(short, long, requires("cairo_input"))] + #[arg(short, long, requires("pre_processor_output"))] output_file: Option, /// Path to save pie file /// /// This will trigger processing(=pie generation) step - #[arg(short, long, requires("cairo_input"))] - pie_file: Option, + #[arg(short, long, requires("pre_processor_output"))] + cairo_pie_file: Option, }, } diff --git a/cli/src/common.rs b/cli/src/common.rs index 8819ec93..e3eae6a3 100644 --- a/cli/src/common.rs +++ b/cli/src/common.rs @@ -4,20 +4,25 @@ use alloy::{ }; use anyhow::Result; use hdp_preprocessor::{ - compile::{module::ModuleCompilerConfig, CompileConfig}, - PreProcessor, + compile::config::CompilerConfig, module_registry::ModuleRegistry, PreProcessor, + PreProcessorError, }; use hdp_primitives::{ + constant::{DEFAULT_DRY_CAIRO_RUN_CAIRO_FILE, DEFAULT_SOUND_CAIRO_RUN_CAIRO_FILE}, processed_types::cairo_format::AsCairoFormat, solidity_types::{ datalake_compute::BatchedDatalakeCompute, traits::{BatchedDatalakeComputeCodecs, DatalakeComputeCodecs}, }, - task::datalake::{ - block_sampled::BlockSampledDatalake, compute::Computation, envelope::DatalakeEnvelope, - transactions::TransactionsInBlockDatalake, DatalakeCompute, + task::{ + datalake::{ + block_sampled::BlockSampledDatalake, compute::Computation, envelope::DatalakeEnvelope, + transactions::TransactionsInBlockDatalake, DatalakeCompute, + }, + TaskEnvelope, }, }; +use hdp_provider::evm::config::EvmProviderConfig; use std::{fs, path::PathBuf}; use tracing_subscriber::FmtSubscriber; @@ -30,6 +35,7 @@ use crate::{ commands::{DataLakeCommands, HDPCli, HDPCliCommands}, config::Config, interactive, + module_config::ModuleConfig, }; pub async fn run() -> anyhow::Result<()> { @@ -43,9 +49,9 @@ pub async fn run() -> anyhow::Result<()> { allow_process, rpc_url, chain_id, + preprocessor_output_file, output_file, - cairo_input, - pie_file, + cairo_pie_file, aggregate_fn_id, aggregate_fn_ctx, command, @@ -92,14 +98,14 @@ pub async fn run() -> anyhow::Result<()> { // if allow_process is true, then run the processor if allow_process { - handle_run( + datalake_entry_run( Some(encoded_computes_string), Some(encoded_datalakes_string), rpc_url, chain_id, + preprocessor_output_file, output_file, - cairo_input, - pie_file, + cairo_pie_file, ) .await? } @@ -112,26 +118,50 @@ pub async fn run() -> anyhow::Result<()> { let decoded_task = DatalakeCompute::decode(&datalake, &task)?; info!("Decoded task: {:#?}", decoded_task); } - HDPCliCommands::Run { + HDPCliCommands::RunDatalake { tasks, datalakes, rpc_url, chain_id, + preprocessor_output_file, output_file, - cairo_input, - pie_file, + cairo_pie_file, } => { - handle_run( + datalake_entry_run( tasks, datalakes, rpc_url, chain_id, + preprocessor_output_file, output_file, - cairo_input, - pie_file, + cairo_pie_file, ) .await? } + HDPCliCommands::RunModule { + class_hash, + local_class_path, + module_inputs, + module_registry_rpc_url, + rpc_url, + chain_id, + preprocessor_output_file, + output_file, + cairo_pie_file, + } => { + module_entry_run( + class_hash, + local_class_path, + module_inputs, + module_registry_rpc_url, + rpc_url, + chain_id, + preprocessor_output_file, + output_file, + cairo_pie_file, + ) + .await?; + } } let duration_run = start_run.elapsed(); info!("HDP Cli Finished in: {:?}", duration_run); @@ -150,62 +180,113 @@ fn init_cli() -> Result { Ok(cli) } -pub async fn handle_run( +#[allow(clippy::too_many_arguments)] +pub async fn module_entry_run( + class_hash: Option, + local_class_path: Option, + module_inputs: Vec, + module_registry_rpc_url: Option, + rpc_url: Option, + chain_id: Option, + preprocessor_output_file: Option, + output_file: Option, + cairo_pie_file: Option, +) -> Result<()> { + let config = ModuleConfig::init(rpc_url, chain_id, module_registry_rpc_url).await; + let module_registry = ModuleRegistry::new(config.module_registry_rpc_url.clone()); + let module = module_registry + .get_extended_module_from_class_source_string(class_hash, local_class_path, module_inputs) + .await?; + // TODO: for now, we only support one task if its a module + let tasks = vec![TaskEnvelope::Module(module)]; + let provider_config = config.evm_provider.clone(); + + handle_running_tasks( + provider_config, + tasks, + preprocessor_output_file, + output_file, + cairo_pie_file, + ) + .await?; + Ok(()) +} + +pub async fn datalake_entry_run( tasks: Option, datalakes: Option, rpc_url: Option, chain_id: Option, + pre_processor_output: Option, output_file: Option, - cairo_input: Option, - pie_file: Option, + cairo_pie_file: Option, ) -> Result<()> { - // TODO: module config is not used rn, hard coded url - let url: Url = "http://localhost:3030".parse()?; - let program_path = "./build/compiled_cairo/hdp.json"; let config = Config::init(rpc_url, datalakes, tasks, chain_id).await; + let tasks = BatchedDatalakeCompute::decode(&config.datalakes, &config.tasks) + .map_err(PreProcessorError::DecodeError)?; + let tasks = tasks + .into_iter() + .map(TaskEnvelope::DatalakeCompute) + .collect::>(); - let module_config = ModuleCompilerConfig { - module_registry_rpc_url: url, - program_path: PathBuf::from(&program_path), - }; + handle_running_tasks( + config.evm_provider.clone(), + tasks, + pre_processor_output, + output_file, + cairo_pie_file, + ) + .await?; + Ok(()) +} - let compile_config = CompileConfig { - provider: config.evm_provider.clone(), - module: module_config, +async fn handle_running_tasks( + evm_config: EvmProviderConfig, + tasks: Vec, + pre_processor_output_file: Option, + output_file: Option, + cairo_pie_file: Option, +) -> Result<()> { + let compiler_config = CompilerConfig { + dry_run_program_path: PathBuf::from(&DEFAULT_DRY_CAIRO_RUN_CAIRO_FILE), + provider_config: evm_config, }; + let preprocessor = PreProcessor::new_with_config(compiler_config); + let preprocessor_result = preprocessor.process(tasks).await?; - let preprocessor = PreProcessor::new_with_config(compile_config); - let result = preprocessor - .process_from_serialized(config.datalakes.clone(), config.tasks.clone()) - .await?; - - if cairo_input.is_none() { + if pre_processor_output_file.is_none() { info!("Finished pre processing the data"); Ok(()) } else { - let input_string = serde_json::to_string_pretty(&result.as_cairo_format()) + let input_string = serde_json::to_string_pretty(&preprocessor_result.as_cairo_format()) .map_err(|e| anyhow::anyhow!("Failed to serialize preprocessor result: {}", e))?; - if let Some(input_file_path) = cairo_input { - fs::write(&input_file_path, input_string.clone()) + if let Some(input_file_path) = pre_processor_output_file { + fs::write(&input_file_path, input_string) .map_err(|e| anyhow::anyhow!("Unable to write input file: {}", e))?; info!( "Finished pre processing the data, saved the input file in {}", input_file_path.display() ); - if output_file.is_none() && pie_file.is_none() { + if output_file.is_none() && cairo_pie_file.is_none() { Ok(()) } else { info!("Starting processing the data... "); let output_file_path = output_file .ok_or_else(|| anyhow::anyhow!("Output file path should be specified"))?; - let pie_file_path = - pie_file.ok_or_else(|| anyhow::anyhow!("PIE path should be specified"))?; - let processor = Processor::new(PathBuf::from(program_path)); - let processor_result = processor.process(result, pie_file_path.clone()).await?; - let output_string = serde_json::to_string_pretty(&processor_result) - .map_err(|e| anyhow::anyhow!("Failed to serialize processor result: {}", e))?; - fs::write(&output_file_path, output_string) - .map_err(|e| anyhow::anyhow!("Unable to write output file: {}", e))?; + let pie_file_path = cairo_pie_file + .ok_or_else(|| anyhow::anyhow!("PIE path should be specified"))?; + let processor = Processor::new(PathBuf::from(DEFAULT_SOUND_CAIRO_RUN_CAIRO_FILE)); + let processor_result = processor + .process(preprocessor_result, &pie_file_path) + .await?; + fs::write( + &output_file_path, + serde_json::to_string_pretty(&processor_result).map_err(|e| { + anyhow::anyhow!("Failed to serialize processor result: {}", e) + })?, + ) + .map_err(|e| anyhow::anyhow!("Unable to write output file: {}", e))?; + info!( "Finished processing the data, saved the output file in {} and pie file in {}", output_file_path.display(), diff --git a/cli/src/config.rs b/cli/src/config.rs index a1f1afcb..0cfc83ea 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -2,7 +2,7 @@ use alloy::{ primitives::{Bytes, ChainId}, transports::http::reqwest::Url, }; -use hdp_provider::evm::provider::EvmProviderConfig; +use hdp_provider::evm::config::EvmProviderConfig; use std::env; use tokio::sync::OnceCell; diff --git a/cli/src/interactive.rs b/cli/src/interactive.rs index 17f6a7fc..a71c3d7b 100644 --- a/cli/src/interactive.rs +++ b/cli/src/interactive.rs @@ -25,7 +25,7 @@ use inquire::{InquireError, Select}; use std::{path::PathBuf, str::FromStr}; use tracing::error; -use crate::common::handle_run; +use crate::common::datalake_entry_run; pub async fn run_interactive() -> anyhow::Result<()> { println!("Welcome to Herodotus Data Processor interactive CLI! 🛰️"); @@ -296,7 +296,7 @@ pub async fn run_interactive() -> anyhow::Result<()> { .prompt()? .into(); - handle_run( + datalake_entry_run( Some(encoded_computes_bytes), Some(encoded_datalakes_bytes), rpc_url, diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 20d901a0..9135ad9d 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -2,5 +2,6 @@ pub mod commands; pub mod common; pub mod config; pub mod interactive; +pub mod module_config; pub use common::run; diff --git a/cli/src/module_config.rs b/cli/src/module_config.rs new file mode 100644 index 00000000..8e57b8a1 --- /dev/null +++ b/cli/src/module_config.rs @@ -0,0 +1,58 @@ +use alloy::{primitives::ChainId, transports::http::reqwest::Url}; +use hdp_provider::evm::config::EvmProviderConfig; + +use std::env; +use tokio::sync::OnceCell; + +pub static MODULE_CONFIG: OnceCell = OnceCell::const_new(); + +/// Configuration for the CLI +#[derive(Debug)] +pub struct ModuleConfig { + pub evm_provider: EvmProviderConfig, + pub module_registry_rpc_url: Url, +} + +impl ModuleConfig { + pub async fn init( + cli_rpc_url: Option, + cli_chain_id: Option, + cli_module_registry_rpc_url: Option, + ) -> &'static Self { + let chain_id = cli_chain_id.unwrap_or_else(|| { + env::var("CHAIN_ID") + .expect("CHAIN_ID must be set") + .parse() + .expect("CHAIN_ID must be a number") + }); + let rpc_url = cli_rpc_url.unwrap_or_else(|| { + env::var("RPC_URL") + .expect("RPC_URL must be set") + .parse() + .expect("RPC_URL must be a valid URL") + }); + let rpc_chunk_size = env::var("RPC_CHUNK_SIZE") + .unwrap_or_else(|_| "40".to_string()) + .parse() + .expect("RPC_CHUNK_SIZE must be a number"); + let module_registry_rpc_url = cli_module_registry_rpc_url.unwrap_or_else(|| { + env::var("MODULE_REGISTRY_RPC_URL") + .expect("MODULE_REGISTRY_RPC_URL must be set") + .parse() + .expect("MODULE_REGISTRY_RPC_URL must be a valid URL") + }); + + MODULE_CONFIG + .get_or_init(|| async { + ModuleConfig { + evm_provider: EvmProviderConfig { + rpc_url, + chain_id, + max_requests: rpc_chunk_size, + }, + module_registry_rpc_url, + } + }) + .await + } +} diff --git a/cli/tests/integration_test.rs b/cli/tests/integration_test.rs index f1504237..d0e3921a 100644 --- a/cli/tests/integration_test.rs +++ b/cli/tests/integration_test.rs @@ -1,46 +1,34 @@ mod integration_test { - use std::path::PathBuf; - use alloy::transports::http::reqwest::Url; use hdp_preprocessor::{ - compile::{module::ModuleCompilerConfig, CompileConfig}, - PreProcessor, + compile::config::CompilerConfig, module_registry::ModuleRegistry, PreProcessor, }; use hdp_primitives::{ aggregate_fn::AggregationFunction, - task::datalake::{ - block_sampled::{BlockSampledCollection, BlockSampledDatalake, HeaderField}, - compute::Computation, - envelope::DatalakeEnvelope, - DatalakeCompute, + processed_types::cairo_format::AsCairoFormat, + task::{ + datalake::{ + block_sampled::{BlockSampledCollection, BlockSampledDatalake, HeaderField}, + compute::Computation, + envelope::DatalakeEnvelope, + DatalakeCompute, + }, + TaskEnvelope, }, }; use hdp_processor::Processor; - use hdp_provider::evm::provider::EvmProviderConfig; - // Non-paid personal alchemy endpoint - const SEPOLIA_RPC_URL: &str = - "https://eth-sepolia.g.alchemy.com/v2/xar76cftwEtqTBWdF4ZFy9n8FLHAETDv"; + use std::{fs, path::PathBuf}; + const STARKNET_SEPOLIA_RPC: &str = "https://starknet-sepolia.g.alchemy.com/v2/lINonYKIlp4NH9ZI6wvqJ4HeZj7T4Wm6"; - const PREPROCESS_PROGRAM_PATH: &str = "../../build/compiled_cairo/hdp.json"; + const DRY_RUN_PROGRAM_PATH: &str = "../build/compiled_cairo/contract_dry_run.json"; + const PREPROCESS_PROGRAM_PATH: &str = "../build/compiled_cairo/hdp.json"; const PIE_PATH: &str = "./cairo.pie"; fn init_preprocessor() -> PreProcessor { - let module_config = ModuleCompilerConfig { - module_registry_rpc_url: Url::parse(STARKNET_SEPOLIA_RPC).unwrap(), - program_path: PathBuf::from(PREPROCESS_PROGRAM_PATH), - }; - let provider_config = EvmProviderConfig { - rpc_url: Url::parse(SEPOLIA_RPC_URL).unwrap(), - chain_id: 11155111, - max_requests: 100, - }; - - let compile_config = CompileConfig { - provider: provider_config, - module: module_config, - }; + let compile_config = CompilerConfig::default() + .with_dry_run_program_path(PathBuf::from(DRY_RUN_PROGRAM_PATH)); PreProcessor::new_with_config(compile_config) } @@ -57,7 +45,7 @@ mod integration_test { let start_process = std::time::Instant::now(); let tasks = vec![ - DatalakeCompute { + TaskEnvelope::DatalakeCompute(DatalakeCompute { compute: Computation::new(AggregationFunction::MIN, None), datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { block_range_start: 10001, @@ -65,8 +53,8 @@ mod integration_test { increment: 1, sampled_property: BlockSampledCollection::Header(HeaderField::Number), }), - }, - DatalakeCompute { + }), + TaskEnvelope::DatalakeCompute(DatalakeCompute { compute: Computation::new(AggregationFunction::AVG, None), datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { block_range_start: 10003, @@ -74,16 +62,119 @@ mod integration_test { increment: 1, sampled_property: BlockSampledCollection::Header(HeaderField::Number), }), - }, + }), + ]; + + let preprocessed_result = pre_processor.process(tasks).await.unwrap(); + let preprocessor_end_process = start_process.elapsed(); + println!("Preprocessed result: {:#?}", preprocessed_result); + + // write + fs::write( + "preprocessed_result.json", + serde_json::to_string_pretty(&preprocessed_result.as_cairo_format()).unwrap(), + ) + .expect("Unable to write file"); + + let start_process = std::time::Instant::now(); + let processed_result = processor + .process(preprocessed_result, &PathBuf::from(PIE_PATH)) + .await + .unwrap(); + let processor_end_process = start_process.elapsed(); + println!("Processed result: {:#?}", processed_result); + + println!("Preprocess time: {:?}", preprocessor_end_process); + println!("Process time: {:?}", processor_end_process); + } + + #[ignore = "ignore for now"] + #[tokio::test] + async fn test_integration_2() { + let pre_processor = init_preprocessor(); + let processor = init_processor(); + let start_process = std::time::Instant::now(); + + let tasks = vec![ + TaskEnvelope::DatalakeCompute(DatalakeCompute { + compute: Computation::new(AggregationFunction::MIN, None), + datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { + block_range_start: 10001, + block_range_end: 10005, + increment: 1, + sampled_property: BlockSampledCollection::Header(HeaderField::Number), + }), + }), + // TaskEnvelope::Module(Module::from_tag( + // ModuleTag::AccountBalanceExample, + // vec![felt!("1"), felt!("0")], + // )), ]; let preprocessed_result = pre_processor.process(tasks).await.unwrap(); let preprocessor_end_process = start_process.elapsed(); println!("Preprocessed result: {:#?}", preprocessed_result); + // write + fs::write( + "preprocessed_result2.json", + serde_json::to_string_pretty(&preprocessed_result.as_cairo_format()).unwrap(), + ) + .expect("Unable to write file"); + + let start_process = std::time::Instant::now(); + let processed_result = processor + .process(preprocessed_result, &PathBuf::from(PIE_PATH)) + .await + .unwrap(); + let processor_end_process = start_process.elapsed(); + println!("Processed result: {:#?}", processed_result); + + println!("Preprocess time: {:?}", preprocessor_end_process); + println!("Process time: {:?}", processor_end_process); + } + + #[ignore = "ignore for now"] + #[tokio::test] + async fn test_integration_3() { + let pre_processor = init_preprocessor(); + let processor = init_processor(); + let start_process = std::time::Instant::now(); + + let url = Url::parse(STARKNET_SEPOLIA_RPC).unwrap(); + let module_regisry = ModuleRegistry::new(url); + let module = module_regisry + .get_extended_module_from_class_source_string( + Some( + "0x02aacf92216d1ae71fbdaf3f41865c08f32317b37be18d8c136d442e94cdd823" + .to_string(), + ), + None, + vec![ + "0x4F21E5".to_string(), + "0x4F21E8".to_string(), + "0x13cb6ae34a13a0977f4d7101ebc24b87bb23f0d5".to_string(), + ], + ) + .await + .unwrap(); + + let tasks = vec![TaskEnvelope::Module(module)]; + + let preprocessed_result = pre_processor.process(tasks).await.unwrap(); + let preprocessor_end_process = start_process.elapsed(); + println!("Preprocessed result: {:#?}", preprocessed_result); + + // write + fs::write( + "preprocessed_result3.json", + serde_json::to_string_pretty(&preprocessed_result.as_cairo_format()).unwrap(), + ) + .expect("Unable to write file"); + let start_process = std::time::Instant::now(); let processed_result = processor - .process(preprocessed_result, PathBuf::from(PIE_PATH)) + .process(preprocessed_result, &PathBuf::from(PIE_PATH)) .await .unwrap(); let processor_end_process = start_process.elapsed(); diff --git a/crates/cairo-runner/Cargo.toml b/crates/cairo-runner/Cargo.toml index 66bbccfa..d514e0e4 100644 --- a/crates/cairo-runner/Cargo.toml +++ b/crates/cairo-runner/Cargo.toml @@ -23,4 +23,5 @@ serde = { workspace = true } serde_with = { workspace = true } serde_json = { workspace = true } starknet-crypto = { workspace = true } +starknet = { workspace = true } thiserror.workspace = true diff --git a/crates/cairo-runner/fixtures/dry_run_input.json b/crates/cairo-runner/fixtures/dry_run_input.json new file mode 100644 index 00000000..99c28322 --- /dev/null +++ b/crates/cairo-runner/fixtures/dry_run_input.json @@ -0,0 +1,1959 @@ +{ + "dry_run_output_path": "dry_run_output.json", + "modules": [ + { + "inputs": [ + "0x4f21e5", + "0x4f21e8", + "0x13cb6ae34a13a0977f4d7101ebc24b87bb23f0d5" + ], + "module_class": { + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "compiler_version": "2.6.4", + "bytecode": [ + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0xfffffffffffffffffffffffffffff6f0", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x11d", + "0x4825800180007ffa", + "0x910", + "0x400280007ff97fff", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0x125", + "0x482680017ff98000", + "0x1", + "0x20680017fff7ffa", + "0x104", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff47fff8000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xde", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffe", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480080007ff57fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480080017ff37fff", + "0x400080027ff27ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0xc9", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x482480017ffe8000", + "0xffffffffffffffffffffffff00000000", + "0x400080017ff77fff", + "0x482480017ff78000", + "0x2", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff47fff8000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x9b", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffe", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480080007ff57fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480080017ff37fff", + "0x400080027ff27ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x86", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x482480017ffe8000", + "0xffffffffffffffffffffffff00000000", + "0x400080017ff77fff", + "0x482480017ff78000", + "0x2", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff48000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x5b", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ff77fff8000", + "0x48127fba7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x305", + "0x482480017fff8000", + "0x304", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fb8", + "0xa0a", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff27fff", + "0x10780017fff7fff", + "0x2b", + "0x4824800180007fb8", + "0xa0a", + "0x400080007ff37fff", + "0x482480017ff38000", + "0x1", + "0x48127ffe7fff8000", + "0x480a7ffb7fff8000", + "0x48127fe47fff8000", + "0x48127fec7fff8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x48127fd87fff8000", + "0x48127fd87fff8000", + "0x48127fef7fff8000", + "0x1104800180018000", + "0x132", + "0x20680017fff7ffc", + "0xf", + "0x40780017fff7fff", + "0x1", + "0x400080007fff7ffc", + "0x400080017fff7ffd", + "0x48127ff87fff8000", + "0x48127ff87fff8000", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x482480017ffa8000", + "0x2", + "0x208b7fff7fff7ffe", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff08000", + "0x1", + "0x48127fb37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202334", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127fbb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482480017ff28000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x8", + "0x48127ff27fff8000", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fbb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482480017ff28000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x8", + "0x48127ff27fff8000", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fc47fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fd27fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x480280007ffc8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x29", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", + "0x1", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xa", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff77fff8000", + "0x48127ffb7fff8000", + "0x10780017fff7fff", + "0x16", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0xc", + "0x40780017fff7fff", + "0x5", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffd", + "0x60", + "0x48307ffb80007ffc", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffa8000", + "0x1", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff78000", + "0x10780017fff7fff", + "0x8", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x29", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", + "0x1", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xa", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff77fff8000", + "0x48127ffb7fff8000", + "0x10780017fff7fff", + "0x16", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0xc", + "0x40780017fff7fff", + "0x5", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffd", + "0xb", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127fec7fff8000", + "0x48127fec7fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0xf", + "0x48127fec7fff8000", + "0x48127fec7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ff58000", + "0xffffffffffffffffffffffffffffa196", + "0x400280007ff47fff", + "0x10780017fff7fff", + "0xb2", + "0x4825800180007ff5", + "0x5e6a", + "0x400280007ff47fff", + "0x48297ff880017ff7", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280017ff47fff", + "0x10780017fff7fff", + "0xd", + "0x400280017ff47fff", + "0x482680017ff48000", + "0x2", + "0x48127ffc7fff8000", + "0x480a7ff67fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ff97fff8000", + "0x480a7ffa7fff8000", + "0x480a7ff77fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff48000", + "0x2", + "0x48127ffb7fff8000", + "0x480a7ff67fff8000", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x480680017fff8000", + "0xaa36a7", + "0x480a7ff77fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0xa1", + "0x20680017fff7ffd", + "0x84", + "0x48327fff7ffa8001", + "0xa0680017fff7fff", + "0x7", + "0x4824800180007fff", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0xc", + "0x400080007ff87fff", + "0x40780017fff7fff", + "0x1", + "0x482480017ff78000", + "0x1", + "0x48127ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0x7", + "0x482480017ff78000", + "0x1", + "0x48127ffe7fff8000", + "0x480680017fff8000", + "0x1", + "0x48327ff87ff98001", + "0xa0680017fff7fff", + "0x7", + "0x4824800180007fff", + "0x100000000000000000000000000000000", + "0x400080007ffa7fff", + "0x10780017fff7fff", + "0xc", + "0x400080007ffb7fff", + "0x40780017fff7fff", + "0x5", + "0x482480017ff68000", + "0x1", + "0x48127ff97fff8000", + "0x48127ff57fff8000", + "0x48127ff57fff8000", + "0x10780017fff7fff", + "0x1c", + "0x480680017fff8000", + "0x1", + "0x48307fff7ffa8001", + "0xa0680017fff7fff", + "0x7", + "0x4824800180007fff", + "0x100000000000000000000000000000000", + "0x400080017ff67fff", + "0x10780017fff7fff", + "0xc", + "0x400080017ff77fff", + "0x40780017fff7fff", + "0x1", + "0x482480017ff68000", + "0x2", + "0x48127ffa7fff8000", + "0x48127ffc7fff8000", + "0x48127ff57fff8000", + "0x10780017fff7fff", + "0x8", + "0x482480017ff68000", + "0x2", + "0x48127ffa7fff8000", + "0x48127ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x20680017fff7fff", + "0x2f", + "0x480680017fff8000", + "0x1", + "0xa0680017fff8000", + "0x8", + "0x48327ffe7ff78000", + "0x4824800180007fff", + "0x100000000", + "0x400080007ff87fff", + "0x10780017fff7fff", + "0x14", + "0x48327ffe7ff78001", + "0x4824800180007fff", + "0xffffffffffffffffffffffff00000000", + "0x400080007ff87ffe", + "0x482480017ff88000", + "0x1", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x48127ffc7fff8000", + "0x480a7ff87fff8000", + "0x48127ff47fff8000", + "0x48127ff47fff8000", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffff78", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x7533325f616464204f766572666c6f77", + "0x400080007ffe7fff", + "0x482480017ff68000", + "0x1", + "0x48127fe37fff8000", + "0x48127fe37fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x753235365f616464204f766572666c6f77", + "0x400080007ffe7fff", + "0x48127ffa7fff8000", + "0x48127fe77fff8000", + "0x48127fe77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff48000", + "0x1", + "0x480a7ff57fff8000", + "0x480a7ff67fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x1", + "0xa0680017fff8004", + "0xe", + "0x4824800180047ffe", + "0x800000000000000000000000000000000000000000000000000000000000000", + "0x484480017ffe8000", + "0x110000000000000000", + "0x48307ffe7fff8002", + "0x480280007ff67ffc", + "0x480280017ff67ffc", + "0x402480017ffb7ffd", + "0xffffffffffffffeeffffffffffffffff", + "0x400280027ff67ffd", + "0x10780017fff7fff", + "0xce", + "0x484480017fff8001", + "0x8000000000000000000000000000000", + "0x48307fff80007ffd", + "0x480280007ff67ffd", + "0x480280017ff67ffd", + "0x402480017ffc7ffe", + "0xf8000000000000000000000000000000", + "0x400280027ff67ffe", + "0x40780017fff7fff", + "0x1", + "0x400180007fff7ff9", + "0x400180017fff7ffa", + "0x400180027fff7ffb", + "0x400180037fff7ffc", + "0x400180047fff7ffd", + "0x480680017fff8000", + "0x0", + "0x48127ffe7fff8000", + "0x482480017ffd8000", + "0x5", + "0x482680017ff68000", + "0x3", + "0x480680017fff8000", + "0x43616c6c436f6e7472616374", + "0x400280007ff87fff", + "0x400380017ff87ff7", + "0x400280027ff87ff4", + "0x400280037ff87ffb", + "0x400280047ff87ffc", + "0x400280057ff87ffd", + "0x480280077ff88000", + "0x20680017fff7fff", + "0xa2", + "0x480280087ff88000", + "0x480280097ff88000", + "0x480680017fff8000", + "0x0", + "0x480280067ff88000", + "0x482680017ff88000", + "0xa", + "0x480280087ff88000", + "0x480280097ff88000", + "0x48307ff980007ffa", + "0xa0680017fff8000", + "0x6", + "0x48307ffe80007ff9", + "0x400080007ff37fff", + "0x10780017fff7fff", + "0x81", + "0x482480017ff98000", + "0x1", + "0x48307fff80007ffd", + "0x400080007ff27fff", + "0x48307ff77ff58000", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x16", + "0x480080017fef8003", + "0x480080027fee8003", + "0x4844800180017ffe", + "0x100000000000000000000000000000000", + "0x483080017ffd7ffb", + "0x482480017fff7ffd", + "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", + "0x20680017fff7ffc", + "0x6", + "0x402480017fff7ffd", + "0xffffffffffffffffffffffffffffffff", + "0x10780017fff7fff", + "0x4", + "0x402480017ffe7ffd", + "0xf7ffffffffffffef0000000000000000", + "0x400080037fea7ffd", + "0x20680017fff7ffe", + "0x56", + "0x402780017fff7fff", + "0x1", + "0x400080017fef7ffe", + "0x480680017fff8000", + "0x1", + "0x48307ff680007ff7", + "0xa0680017fff8000", + "0x6", + "0x48307ffe80007ffd", + "0x400080027feb7fff", + "0x10780017fff7fff", + "0x39", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400080027fea7fff", + "0x48307ffb7ff28000", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x16", + "0x480080037fe78003", + "0x480080047fe68003", + "0x4844800180017ffe", + "0x100000000000000000000000000000000", + "0x483080017ffd7ffb", + "0x482480017fff7ffd", + "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", + "0x20680017fff7ffc", + "0x6", + "0x402480017fff7ffd", + "0xffffffffffffffffffffffffffffffff", + "0x10780017fff7fff", + "0x4", + "0x402480017ffe7ffd", + "0xf7ffffffffffffef0000000000000000", + "0x400080057fe27ffd", + "0x20680017fff7ffe", + "0x10", + "0x402780017fff7fff", + "0x1", + "0x400080037fe77ffe", + "0x40780017fff7fff", + "0x7", + "0x482480017fe08000", + "0x4", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x0", + "0x48127feb7fff8000", + "0x48127ff27fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x6", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x9", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e646578206f7574206f6620626f756e6473", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x3", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x8", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x4", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x11", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e646578206f7574206f6620626f756e6473", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x1", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1d", + "0x48127fe07fff8000", + "0x480280067ff88000", + "0x482680017ff88000", + "0xa", + "0x480680017fff8000", + "0x1", + "0x480280087ff88000", + "0x480280097ff88000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x21", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482680017ff68000", + "0x3", + "0x480a7ff77fff8000", + "0x480a7ff87fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe" + ], + "bytecode_segment_lengths": [ + 305, + 181, + 200, + 237 + ], + "hints": [ + [ + 0, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x910" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 40, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -1 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 44, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 86, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -1 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 90, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 136, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 155, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0xa0a" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -71 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 184, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 205, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 220, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 241, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 262, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 276, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 290, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 486, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x5e6a" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -11 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 497, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 530, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 553, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 573, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 600, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "FP", + "offset": -9 + }, + "b": { + "Deref": { + "register": "AP", + "offset": -1 + } + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 626, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 643, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 669, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 688, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": 4 + } + } + } + ] + ], + [ + 692, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": 3 + } + }, + "scalar": { + "Immediate": "0x110000000000000000" + }, + "max_x": { + "Immediate": "0xffffffffffffffffffffffffffffffff" + }, + "x": { + "register": "AP", + "offset": -2 + }, + "y": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 702, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "scalar": { + "Immediate": "0x8000000000000000000000000000000" + }, + "max_x": { + "Immediate": "0xffffffffffffffffffffffffffffffff" + }, + "x": { + "register": "AP", + "offset": -1 + }, + "y": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 710, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 732, + [ + { + "SystemCall": { + "system": { + "Deref": { + "register": "FP", + "offset": -8 + } + } + } + } + ] + ], + [ + 745, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 757, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 759, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 3 + }, + "remainder": { + "register": "AP", + "offset": 4 + } + } + } + ] + ], + [ + 783, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 795, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 797, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 3 + }, + "remainder": { + "register": "AP", + "offset": 4 + } + } + } + ] + ], + [ + 829, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 846, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 863, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 880, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 908, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ] + ], + "pythonic_hints": [ + [ + 0, + [ + "memory[ap + 0] = 2320 <= memory[fp + -6]" + ] + ], + [ + 40, + [ + "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" + ] + ], + [ + 44, + [ + "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" + ] + ], + [ + 86, + [ + "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" + ] + ], + [ + 90, + [ + "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" + ] + ], + [ + 136, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 155, + [ + "memory[ap + 0] = 2570 <= memory[ap + -71]" + ] + ], + [ + 184, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 205, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 220, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 241, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 262, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 276, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 290, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 486, + [ + "memory[ap + 0] = 24170 <= memory[fp + -11]" + ] + ], + [ + 497, + [ + "memory[ap + -1] = memory[ap + 0] < 4294967296" + ] + ], + [ + 530, + [ + "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" + ] + ], + [ + 553, + [ + "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" + ] + ], + [ + 573, + [ + "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" + ] + ], + [ + 600, + [ + "memory[ap + 0] = (memory[fp + -9] + memory[ap + -1]) % PRIME < 4294967296" + ] + ], + [ + 626, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 643, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 669, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 688, + [ + "memory[ap + 4] = memory[ap + -1] < 3618502788666131106986593281521497120414687020801267626233049500247285301248" + ] + ], + [ + 692, + [ + "\n(value, scalar) = (memory[ap + 3], 313594649253062377472)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -2] = x\nmemory[ap + -1] = y\n" + ] + ], + [ + 702, + [ + "\n(value, scalar) = (memory[ap + -2], 10633823966279326983230456482242756608)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -1] = x\nmemory[ap + 0] = y\n" + ] + ], + [ + 710, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 732, + [ + "syscall_handler.syscall(syscall_ptr=memory[fp + -8])" + ] + ], + [ + 745, + [ + "memory[ap + 0] = memory[ap + -6] < memory[ap + -1]" + ] + ], + [ + 757, + [ + "memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456" + ] + ], + [ + 759, + [ + "(memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456)" + ] + ], + [ + 783, + [ + "memory[ap + 0] = memory[ap + -2] < memory[ap + -1]" + ] + ], + [ + 795, + [ + "memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456" + ] + ], + [ + 797, + [ + "(memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456)" + ] + ], + [ + 829, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 846, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 863, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 880, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 908, + [ + "memory[ap + 0] = segments.add()" + ] + ] + ], + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0xe2054f8a912367e38a22ce773328ff8aabf8082c4120bad9ef085e1dbf29a7", + "offset": 0, + "builtins": [ + "range_check" + ] + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + } + } + } + ] +} \ No newline at end of file diff --git a/crates/cairo-runner/fixtures/dry_run_output.json b/crates/cairo-runner/fixtures/dry_run_output.json index 887111a0..bfbe5229 100644 --- a/crates/cairo-runner/fixtures/dry_run_output.json +++ b/crates/cairo-runner/fixtures/dry_run_output.json @@ -1,82 +1,32 @@ [ { - "key": { - "chain_id": 1, - "block_number": 6203471, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203472, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203473, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203474, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203475, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203476, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203477, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203478, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203479, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" - }, - { - "key": { - "chain_id": 1, - "block_number": 6203480, - "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" - }, - "type": "AccountMemorizerKey" + "fetch_keys": [ + { + "key": { + "chain_id": 11155111, + "block_number": 5186021, + "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" + }, + "type": "AccountMemorizerKey" + }, + { + "key": { + "chain_id": 11155111, + "block_number": 5186022, + "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" + }, + "type": "AccountMemorizerKey" + }, + { + "key": { + "chain_id": 11155111, + "block_number": 5186023, + "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5" + }, + "type": "AccountMemorizerKey" + } + ], + "result": { "low": "0x0", "high": "0x0" }, + "class_hash": "0xc8580f74b6e6e04d8073602ad0c0d55538b56bf8307fefebb6b65b1bbf2a27" } ] diff --git a/crates/cairo-runner/src/dry_run.rs b/crates/cairo-runner/src/dry_run.rs index b1b12882..6ffbc28b 100644 --- a/crates/cairo-runner/src/dry_run.rs +++ b/crates/cairo-runner/src/dry_run.rs @@ -1,7 +1,10 @@ -//! THIS IS WIP, NOT READY FOR USE - -use hdp_primitives::constant::DRY_RUN_OUTPUT_FILE; +use hdp_primitives::constant::DRY_CAIRO_RUN_OUTPUT_FILE; +use hdp_primitives::processed_types::uint256::Uint256; use hdp_provider::key::FetchKeyEnvelope; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use starknet::core::serde::unsigned_field_element::UfeHex; +use starknet_crypto::FieldElement; use std::fs; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -10,6 +13,17 @@ use tracing::info; use crate::CairoRunnerError; +pub type DryRunResult = Vec; + +#[serde_as] +#[derive(Serialize, Deserialize)] +pub struct DryRunnedModule { + pub fetch_keys: Vec, + pub result: Uint256, + #[serde_as(as = "UfeHex")] + pub class_hash: FieldElement, +} + pub struct DryRunner { program_path: PathBuf, } @@ -37,7 +51,7 @@ impl DryRunner { } /// Dry run to return requested values - pub fn run(&self, input_string: String) -> Result, CairoRunnerError> { + pub fn run(&self, input_string: String) -> Result { if input_string.is_empty() { return Err(CairoRunnerError::EmptyInput); } @@ -47,15 +61,16 @@ impl DryRunner { let _ = self._run(input_file_path)?; // parse output to return dry run result - let dry_run_result = self.parse_run(&PathBuf::from(DRY_RUN_OUTPUT_FILE))?; + let dry_run_result = self.parse_run(&PathBuf::from(DRY_CAIRO_RUN_OUTPUT_FILE))?; info!("Dry-runner executed successfully"); Ok(dry_run_result) } /// Parse the output of the dry run command - fn parse_run(&self, input_file_path: &Path) -> Result, CairoRunnerError> { + fn parse_run(&self, input_file_path: &Path) -> Result { let output = fs::read_to_string(input_file_path)?; - let fetch_keys: Vec = serde_json::from_str(&output)?; + let fetch_keys: Vec = serde_json::from_str(&output)?; + // clean up generated input file after parse fs::remove_file(input_file_path)?; Ok(fetch_keys) } @@ -63,20 +78,44 @@ impl DryRunner { #[cfg(test)] mod tests { + use starknet::macros::felt; + use super::*; fn init_dry_runner() -> DryRunner { - let program_path = PathBuf::from("tests/programs/cairo_runner_test.cairo"); + let program_path = PathBuf::from("../../build/compiled_cairo/contract_dry_run.json"); DryRunner::new(program_path) } + #[ignore = "ignore for now"] + #[test] + fn test_dry_run() { + let dry_runner = init_dry_runner(); + let input = fs::read_to_string("./fixtures/dry_run_input.json").unwrap(); + let result = dry_runner.run(input).unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(result[0].fetch_keys.len(), 3); + assert_eq!(result[0].result, Uint256::from_strs("0x0", "0x0").unwrap()); + assert_eq!( + result[0].class_hash, + felt!("0x04df21eb479ae4416fbdc00abab6fab43bff0b8083be4d1fd8602c8fbfbd2274") + ); + } + #[test] fn test_parse_run() { let dry_runner = init_dry_runner(); let path: &Path = Path::new("./fixtures/dry_run_output.json"); - let fetch_keys = dry_runner.parse_run(path).unwrap(); - assert_eq!(fetch_keys.len(), 10); + let modules = dry_runner.parse_run(path).unwrap(); + assert_eq!(modules.len(), 1); + let module = &modules[0]; + assert_eq!(module.fetch_keys.len(), 3); + assert_eq!(module.result, Uint256::from_strs("0x0", "0x0").unwrap()); + assert_eq!( + module.class_hash, + felt!("0xc8580f74b6e6e04d8073602ad0c0d55538b56bf8307fefebb6b65b1bbf2a27") + ) } } diff --git a/crates/cairo-runner/src/input/dry_run.rs b/crates/cairo-runner/src/input/dry_run.rs index 5122d373..d1e2c6e0 100644 --- a/crates/cairo-runner/src/input/dry_run.rs +++ b/crates/cairo-runner/src/input/dry_run.rs @@ -1,7 +1,7 @@ //! The input for the dry-runner. //! This serialized struct will be passed to the dry-runner(cairo-run) as input.json file. -use hdp_primitives::processed_types::module::ProcessedModule; +use hdp_primitives::processed_types::cairo_format; use serde::Serialize; use serde_with::serde_as; use std::path::PathBuf; @@ -9,18 +9,18 @@ use std::path::PathBuf; #[serde_as] #[derive(Serialize)] pub struct DryRunnerProgramInput { - pub fetch_keys_file_path: PathBuf, - pub modules: Vec, + pub dry_run_output_path: PathBuf, + pub modules: Vec, } impl DryRunnerProgramInput { - pub fn new(fetch_keys_file_path: PathBuf, modules: Vec) -> Self { + pub fn new(dry_run_output_path: PathBuf, modules: Vec) -> Self { // TODO: temporary check to ensure only one module is passed if modules.len() != 1 { panic!("Currently DryRunnerProgramInput only supports a single module"); } Self { - fetch_keys_file_path, + dry_run_output_path, modules, } } diff --git a/crates/cairo-runner/src/input/mod.rs b/crates/cairo-runner/src/input/mod.rs index ea1121eb..791d0480 100644 --- a/crates/cairo-runner/src/input/mod.rs +++ b/crates/cairo-runner/src/input/mod.rs @@ -1,2 +1 @@ pub mod dry_run; -pub mod run; diff --git a/crates/cairo-runner/src/input/run.rs b/crates/cairo-runner/src/input/run.rs deleted file mode 100644 index f57d5add..00000000 --- a/crates/cairo-runner/src/input/run.rs +++ /dev/null @@ -1,37 +0,0 @@ -use hdp_primitives::processed_types::{ - block_proofs::ProcessedBlockProofs, cairo_format, module::ProcessedModule, -}; -use serde::Serialize; - -/// input.json file that will be passed to the cairo-run, is generated by this struct. -#[derive(Serialize)] -pub struct RunnerProgramInput { - /// Batched tasks root of all tasks. - pub task_root: String, - /// if every tasks are pre computable, this can be Some - #[serde(skip_serializing_if = "Option::is_none")] - pub result_root: Option, - /// Fetched proofs per each fetch point. - pub proofs: ProcessedBlockProofs, - /// tasks compatible with v2 - pub tasks: Vec, -} - -#[derive(Serialize)] -pub enum InputTask { - #[serde(rename = "datalake_compute")] - DatalakeCompute(cairo_format::ProcessedDatalakeCompute), - #[serde(rename = "module")] - Module(ProcessedModule), -} - -impl RunnerProgramInput { - pub fn new(proofs: ProcessedBlockProofs, task_root: String, tasks: Vec) -> Self { - Self { - task_root, - result_root: None, - tasks, - proofs, - } - } -} diff --git a/crates/cairo-runner/src/lib.rs b/crates/cairo-runner/src/lib.rs index 0490e5eb..93055ad9 100644 --- a/crates/cairo-runner/src/lib.rs +++ b/crates/cairo-runner/src/lib.rs @@ -1,5 +1,4 @@ -use hdp_provider::key::FetchKeyEnvelope; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use thiserror::Error; pub mod dry_run; @@ -35,9 +34,9 @@ pub enum CairoRunnerError { /// Compatible with cairo-run command pub fn cairo_run( - program_path: PathBuf, + program_path: &Path, input_string: String, - pie_file_path: PathBuf, + pie_file_path: &PathBuf, ) -> Result { let cairo_runner = run::Runner::new(program_path); cairo_runner.run(input_string, pie_file_path) @@ -47,7 +46,7 @@ pub fn cairo_run( pub fn cairo_dry_run( program_path: PathBuf, input_string: String, -) -> Result, CairoRunnerError> { +) -> Result { let dry_runner = dry_run::DryRunner::new(program_path); dry_runner.run(input_string) } diff --git a/crates/cairo-runner/src/run.rs b/crates/cairo-runner/src/run.rs index ca466055..1ef7958b 100644 --- a/crates/cairo-runner/src/run.rs +++ b/crates/cairo-runner/src/run.rs @@ -1,10 +1,10 @@ use alloy::primitives::{B256, U256}; -use hdp_primitives::processed_types::uint256::Uint256; +use hdp_primitives::constant::SOUND_CAIRO_RUN_OUTPUT_FILE; use regex::Regex; +use serde::{Deserialize, Serialize}; use std::fs; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; -use std::str::FromStr; use tempfile::NamedTempFile; use tracing::info; @@ -14,8 +14,14 @@ use crate::CairoRunnerError; #[derive(Debug)] pub struct RunResult { pub pie_path: PathBuf, - pub task_results: Vec, + pub cairo_run_output: CairoRunOutput, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CairoRunOutput { + pub tasks_root: B256, pub results_root: B256, + pub results: Vec, } pub struct Runner { @@ -23,8 +29,10 @@ pub struct Runner { } impl Runner { - pub fn new(program_path: PathBuf) -> Self { - Self { program_path } + pub fn new(program_path: &Path) -> Self { + Self { + program_path: program_path.to_path_buf(), + } } fn _run( @@ -55,7 +63,7 @@ impl Runner { pub fn run( &self, input_string: String, - pie_file_path: PathBuf, + pie_file_path: &PathBuf, ) -> Result { if input_string.is_empty() { return Err(CairoRunnerError::EmptyInput); @@ -65,65 +73,30 @@ impl Runner { let input_file_path = input_file.path(); fs::write(input_file_path, input_string).expect("Failed to write input file"); - let output = self._run(input_file_path, &pie_file_path)?; - let (task_results, results_root) = self.parse_run(output)?; - info!("Final result: {:#?}", task_results); - info!("Final result root: {:#?}", results_root); + let output = self._run(input_file_path, pie_file_path)?; + let cairo_run_output = + self.parse_run(output, &PathBuf::from(SOUND_CAIRO_RUN_OUTPUT_FILE))?; + info!("Cairo run output: {:#?}", cairo_run_output); Ok(RunResult { pie_path: pie_file_path.to_owned(), - task_results, - results_root, + cairo_run_output, }) } /// Parse the output of the run command - fn parse_run(&self, output: String) -> Result<(Vec, B256), CairoRunnerError> { + fn parse_run( + &self, + output: String, + cairo_run_output_path: &PathBuf, + ) -> Result { let number_of_steps = Regex::new(r"Number of steps: (\d+)").unwrap(); if let Some(number_of_steps_caps) = number_of_steps.captures(&output) { let number_of_steps = number_of_steps_caps[1].parse::()?; info!("Number of steps: {:#?}", number_of_steps); } - let task_result_re = Regex::new(r"Task Result\((\d+)\): (\S+)").unwrap(); - let mut task_results = vec![]; - for caps in task_result_re.captures_iter(&output) { - let _ = &caps[1]; - let value = &caps[2]; - task_results.push(U256::from_str(value)?); - } - let results_root_re = Regex::new(r"Results Root: (\S+) (\S+)").unwrap(); - if let Some(results_root_caps) = results_root_re.captures(&output) { - let results_root_1 = &results_root_caps[1]; - let results_root_2 = &results_root_caps[2]; - let result_root = Uint256::from_strs(results_root_2, results_root_1)?; - let combined_results_root = result_root.to_combined_string(); - Ok((task_results, combined_results_root)) - } else { - Err(CairoRunnerError::ResultRootNotFound) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_parse_run() { - let program_path = PathBuf::from("../build/compiled_cairo/hdp.json"); - let runner = Runner::new(program_path); - let output = "Task Result(0): 0x01020304\nResults Root: 0x01020304 0x05060708"; - let (task_results, results_root) = runner.parse_run(output.to_string()).unwrap(); - assert_eq!(task_results.len(), 1); - assert_eq!( - task_results[0], - U256::from_str_radix("01020304", 16).unwrap() - ); - assert_eq!( - results_root, - Uint256::from_strs("05060708", "01020304") - .unwrap() - .to_combined_string() - ); + let cairo_run_output_from_file = fs::read_to_string(cairo_run_output_path)?; + let cairo_run_output: CairoRunOutput = serde_json::from_str(&cairo_run_output_from_file)?; + Ok(cairo_run_output) } } diff --git a/crates/primitives/contracts/compiled/account_balance_example.json b/crates/contracts/account_balance_example.compiled_contract_class.json similarity index 58% rename from crates/primitives/contracts/compiled/account_balance_example.json rename to crates/contracts/account_balance_example.compiled_contract_class.json index 1b79c1e2..0fb63a90 100644 --- a/crates/primitives/contracts/compiled/account_balance_example.json +++ b/crates/contracts/account_balance_example.compiled_contract_class.json @@ -1,92 +1,139 @@ { "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.6.3", + "compiler_version": "2.6.4", "bytecode": [ "0xa0680017fff8000", "0x7", "0x482680017ffa8000", - "0xffffffffffffffffffffffffffffea5c", + "0xfffffffffffffffffffffffffffff6f0", "0x400280007ff97fff", "0x10780017fff7fff", - "0xb7", + "0x11d", "0x4825800180007ffa", - "0x15a4", + "0x910", "0x400280007ff97fff", "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0xbf", + "0x125", "0x482680017ff98000", "0x1", "0x20680017fff7ffa", - "0x2c", - "0x48127ff87fff8000", - "0x48127ff87fff8000", - "0x1104800180018000", - "0xb7", - "0x20680017fff7ffb", - "0x10", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", - "0x0", - "0x48127fcf7fff8000", - "0x48127fcf7fff8000", - "0x48127fcf7fff8000", - "0x48127fcf7fff8000", - "0x48127ff57fff8000", - "0x48127ff57fff8000", - "0x48127ff57fff8000", - "0x48127ff57fff8000", + "0x104", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", "0x10780017fff7fff", - "0x2e", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", + "0xa", + "0x482480017ff78000", "0x1", + "0x48127ff77fff8000", "0x480680017fff8000", "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", + "0x48127ff47fff8000", "0x10780017fff7fff", - "0x18", - "0x40780017fff7fff", - "0x29", - "0x48127fcf7fff8000", - "0x48127fcf7fff8000", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", "0x480680017fff8000", "0x1", "0x480680017fff8000", "0x0", + "0x20680017fff7ffe", + "0xde", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffe", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480080007ff57fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480080017ff37fff", + "0x400080027ff27ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0xc9", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x482480017ffe8000", + "0xffffffffffffffffffffffff00000000", + "0x400080017ff77fff", + "0x482480017ff78000", + "0x2", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", "0x480680017fff8000", "0x0", + "0x48127ff47fff8000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", + "0x1", "0x480680017fff8000", "0x0", + "0x20680017fff7ffe", + "0x9b", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffe", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480080007ff57fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480080017ff37fff", + "0x400080027ff27ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x86", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x482480017ffe8000", + "0xffffffffffffffffffffffff00000000", + "0x400080017ff77fff", + "0x482480017ff78000", + "0x2", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", "0x480680017fff8000", "0x0", + "0x480080007ff48000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", "0x480680017fff8000", - "0x0", + "0x1", "0x480680017fff8000", "0x0", - "0x20680017fff7ff7", - "0x5c", - "0x48307ff580007ff6", + "0x20680017fff7ffe", + "0x5b", + "0x48307ffc80007ffd", "0x20680017fff7fff", "0x4", "0x10780017fff7fff", @@ -96,8 +143,8 @@ "0x480680017fff8000", "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", "0x400080007ffe7fff", - "0x48127fc87fff8000", - "0x48127f9d7fff8000", + "0x48127ff77fff8000", + "0x48127fba7fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -106,38 +153,37 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x2f4", + "0x305", "0x482480017fff8000", - "0x2f3", + "0x304", "0x480080007fff8000", "0xa0680017fff8000", "0x9", - "0x4824800180007f9b", + "0x4824800180007fb8", "0xa0a", "0x482480017fff8000", "0x100000000000000000000000000000000", - "0x400080007fc37fff", + "0x400080007ff27fff", "0x10780017fff7fff", - "0x2c", - "0x4824800180007f9b", + "0x2b", + "0x4824800180007fb8", "0xa0a", - "0x400080007fc47fff", - "0x482480017fc48000", + "0x400080007ff37fff", + "0x482480017ff38000", "0x1", "0x48127ffe7fff8000", "0x480a7ffb7fff8000", + "0x48127fe47fff8000", + "0x48127fec7fff8000", "0x480680017fff8000", "0x0", "0x480680017fff8000", "0x0", - "0x480680017fff8000", - "0x0", - "0x48127fef7fff8000", - "0x48127fef7fff8000", - "0x48127fef7fff8000", + "0x48127fd87fff8000", + "0x48127fd87fff8000", "0x48127fef7fff8000", "0x1104800180018000", - "0xfa", + "0x132", "0x20680017fff7ffc", "0xf", "0x40780017fff7fff", @@ -166,9 +212,65 @@ "0x480680017fff8000", "0x4f7574206f6620676173", "0x400080007ffe7fff", - "0x482480017fc18000", + "0x482480017ff08000", + "0x1", + "0x48127fb37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202334", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127fbb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482480017ff28000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x8", + "0x48127ff27fff8000", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fbb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", "0x1", - "0x48127f967fff8000", + "0x208b7fff7fff7ffe", + "0x482480017ff28000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x8", + "0x48127ff27fff8000", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fc47fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -181,8 +283,8 @@ "0x480680017fff8000", "0x4661696c656420746f20646573657269616c697a6520706172616d202331", "0x400080007ffe7fff", - "0x48127fc97fff8000", - "0x48127f9e7fff8000", + "0x48127ffd7fff8000", + "0x48127fd27fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -389,16 +491,14 @@ "0xa0680017fff8000", "0x7", "0x482680017ff58000", - "0xffffffffffffffffffffffffffff9d68", + "0xffffffffffffffffffffffffffffa196", "0x400280007ff47fff", "0x10780017fff7fff", - "0xd6", + "0xb2", "0x4825800180007ff5", - "0x6298", + "0x5e6a", "0x400280007ff47fff", - "0x480680017fff8000", - "0xa", - "0x48317fff80017ff7", + "0x48297ff880017ff7", "0xa0680017fff7fff", "0x7", "0x482480017fff8000", @@ -409,46 +509,29 @@ "0x400280017ff47fff", "0x482680017ff48000", "0x2", - "0x48127ffb7fff8000", + "0x48127ffc7fff8000", "0x480a7ff67fff8000", "0x480680017fff8000", "0x0", - "0x480a7ff87fff8000", "0x480a7ff97fff8000", + "0x480a7ffa7fff8000", "0x480a7ff77fff8000", "0x208b7fff7fff7ffe", - "0x480680017fff8000", - "0x5ea84f", - "0xa0680017fff8000", - "0x8", - "0x48287ff77ffe8000", - "0x4824800180007fff", - "0x100000000", - "0x400280027ff47fff", - "0x10780017fff7fff", - "0xa3", - "0x48287ff77ffe8001", - "0x4824800180007fff", - "0xffffffffffffffffffffffff00000000", - "0x400280027ff47ffe", "0x482680017ff48000", - "0x3", - "0x48127ff67fff8000", + "0x2", + "0x48127ffb7fff8000", "0x480a7ff67fff8000", - "0x480a7ffa7fff8000", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", "0x480680017fff8000", - "0x1", - "0x48127ff77fff8000", - "0x480680017fff8000", - "0x13cb6ae34a13a0977f4d7101ebc24b87bb23f0d5", + "0xaa36a7", + "0x480a7ff77fff8000", + "0x480a7ffd7fff8000", "0x1104800180018000", - "0xb2", + "0xa1", "0x20680017fff7ffd", "0x84", - "0x48327fff7ff98001", + "0x48327fff7ffa8001", "0xa0680017fff7fff", "0x7", "0x4824800180007fff", @@ -471,7 +554,7 @@ "0x48127ffe7fff8000", "0x480680017fff8000", "0x1", - "0x48327ff87ff88001", + "0x48327ff87ff98001", "0xa0680017fff7fff", "0x7", "0x4824800180007fff", @@ -536,14 +619,14 @@ "0x48127fe57fff8000", "0x48127fe57fff8000", "0x48127ffc7fff8000", - "0x48127ff57fff8000", - "0x48127ff57fff8000", - "0x480a7ffa7fff8000", + "0x480a7ff87fff8000", + "0x48127ff47fff8000", + "0x48127ff47fff8000", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffff65", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffff78", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x1", @@ -591,23 +674,6 @@ "0x40780017fff7fff", "0x1", "0x480680017fff8000", - "0x7533325f616464204f766572666c6f77", - "0x400080007ffe7fff", - "0x482680017ff48000", - "0x3", - "0x48127ff47fff8000", - "0x480a7ff67fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", "0x4f7574206f6620676173", "0x400080007ffe7fff", "0x482680017ff48000", @@ -631,57 +697,55 @@ "0x484480017ffe8000", "0x110000000000000000", "0x48307ffe7fff8002", - "0x480280007ff47ffc", - "0x480280017ff47ffc", + "0x480280007ff67ffc", + "0x480280017ff67ffc", "0x402480017ffb7ffd", "0xffffffffffffffeeffffffffffffffff", - "0x400280027ff47ffd", + "0x400280027ff67ffd", "0x10780017fff7fff", - "0xd0", + "0xce", "0x484480017fff8001", "0x8000000000000000000000000000000", "0x48307fff80007ffd", - "0x480280007ff47ffd", - "0x480280017ff47ffd", + "0x480280007ff67ffd", + "0x480280017ff67ffd", "0x402480017ffc7ffe", "0xf8000000000000000000000000000000", - "0x400280027ff47ffe", + "0x400280027ff67ffe", "0x40780017fff7fff", "0x1", - "0x400180007fff7ff7", - "0x400180017fff7ff8", - "0x400180027fff7ff9", - "0x400180037fff7ffa", - "0x400180047fff7ffb", - "0x400180057fff7ffc", - "0x400180067fff7ffd", + "0x400180007fff7ff9", + "0x400180017fff7ffa", + "0x400180027fff7ffb", + "0x400180037fff7ffc", + "0x400180047fff7ffd", "0x480680017fff8000", "0x0", "0x48127ffe7fff8000", "0x482480017ffd8000", - "0x7", - "0x482680017ff48000", + "0x5", + "0x482680017ff68000", "0x3", "0x480680017fff8000", "0x43616c6c436f6e7472616374", - "0x400280007ff67fff", - "0x400380017ff67ff5", - "0x400280027ff67ff4", - "0x400280037ff67ffb", - "0x400280047ff67ffc", - "0x400280057ff67ffd", - "0x480280077ff68000", + "0x400280007ff87fff", + "0x400380017ff87ff7", + "0x400280027ff87ff4", + "0x400280037ff87ffb", + "0x400280047ff87ffc", + "0x400280057ff87ffd", + "0x480280077ff88000", "0x20680017fff7fff", "0xa2", - "0x480280087ff68000", - "0x480280097ff68000", + "0x480280087ff88000", + "0x480280097ff88000", "0x480680017fff8000", "0x0", - "0x480280067ff68000", - "0x482680017ff68000", + "0x480280067ff88000", + "0x482680017ff88000", "0xa", - "0x480280087ff68000", - "0x480280097ff68000", + "0x480280087ff88000", + "0x480280097ff88000", "0x48307ff980007ffa", "0xa0680017fff8000", "0x6", @@ -836,13 +900,13 @@ "0x40780017fff7fff", "0x1d", "0x48127fe07fff8000", - "0x480280067ff68000", - "0x482680017ff68000", + "0x480280067ff88000", + "0x482680017ff88000", "0xa", "0x480680017fff8000", "0x1", - "0x480280087ff68000", - "0x480280097ff68000", + "0x480280087ff88000", + "0x480280097ff88000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x21", @@ -851,10 +915,10 @@ "0x480680017fff8000", "0x4f7074696f6e3a3a756e77726170206661696c65642e", "0x400080007ffe7fff", - "0x482680017ff48000", + "0x482680017ff68000", "0x3", - "0x480a7ff57fff8000", - "0x480a7ff67fff8000", + "0x480a7ff77fff8000", + "0x480a7ff87fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", @@ -862,883 +926,433 @@ "0x1", "0x208b7fff7fff7ffe" ], - "bytecode_segment_lengths": [ - 203, - 181, - 236, - 239 - ], + "bytecode_segment_lengths": [305, 181, 200, 237], "hints": [ [ 0, [ { "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x15a4" - }, - "rhs": { - "Deref": { - "register": "FP", - "offset": -6 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 89, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Immediate": "0x910" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 108, + 40, [ { - "TestLessThanOrEqual": { + "TestLessThan": { "lhs": { - "Immediate": "0xa0a" - }, - "rhs": { - "Deref": { - "register": "AP", - "offset": -100 + "BinOp": { + "op": "Add", + "a": { "register": "AP", "offset": -1 }, + "b": { "Immediate": "0x0" } } }, - "dst": { - "register": "AP", - "offset": 0 - } + "rhs": { "Immediate": "0x100000000" }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 138, + 44, [ { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 159, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": -1 } }, + "scalar": { "Immediate": "0x8000000000000110000000000000000" }, + "max_x": { "Immediate": "0xfffffffffffffffffffffffffffffffe" }, + "x": { "register": "AP", "offset": 0 }, + "y": { "register": "AP", "offset": 1 } } } ] ], [ - 174, + 86, [ { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { "register": "AP", "offset": -1 }, + "b": { "Immediate": "0x0" } + } + }, + "rhs": { "Immediate": "0x100000000" }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 188, + 90, [ { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": -1 } }, + "scalar": { "Immediate": "0x8000000000000110000000000000000" }, + "max_x": { "Immediate": "0xfffffffffffffffffffffffffffffffe" }, + "x": { "register": "AP", "offset": 0 }, + "y": { "register": "AP", "offset": 1 } } } ] ], + [136, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], [ - 384, + 155, [ { "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x6298" - }, - "rhs": { - "Deref": { - "register": "FP", - "offset": -11 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Immediate": "0xa0a" }, + "rhs": { "Deref": { "register": "AP", "offset": -71 } }, + "dst": { "register": "AP", "offset": 0 } } } ] ], + [184, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [205, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [220, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [241, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [262, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [276, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [290, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], [ - 397, + 486, [ { - "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000" - }, - "dst": { - "register": "AP", - "offset": -1 - } + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x5e6a" }, + "rhs": { "Deref": { "register": "FP", "offset": -11 } }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 417, + 497, [ { "TestLessThan": { - "lhs": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -1 - }, - "b": { - "Deref": { - "register": "FP", - "offset": -9 - } - } - } - }, - "rhs": { - "Immediate": "0x100000000" - }, - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Deref": { "register": "AP", "offset": 0 } }, + "rhs": { "Immediate": "0x100000000" }, + "dst": { "register": "AP", "offset": -1 } } } ] ], [ - 447, + 530, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": -1 - } + "lhs": { "Deref": { "register": "AP", "offset": 0 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": -1 } } } ] ], [ - 470, + 553, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": -1 - } + "lhs": { "Deref": { "register": "AP", "offset": 0 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": -1 } } } ] ], [ - 490, + 573, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": 0 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": -1 - } + "lhs": { "Deref": { "register": "AP", "offset": 0 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": -1 } } } ] ], [ - 517, + 600, [ { "TestLessThan": { "lhs": { "BinOp": { "op": "Add", - "a": { - "register": "FP", - "offset": -9 - }, - "b": { - "Deref": { - "register": "AP", - "offset": -1 - } - } + "a": { "register": "FP", "offset": -9 }, + "b": { "Deref": { "register": "AP", "offset": -1 } } } }, - "rhs": { - "Immediate": "0x100000000" - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 543, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 560, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 586, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 603, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } + "rhs": { "Immediate": "0x100000000" }, + "dst": { "register": "AP", "offset": 0 } } } ] ], + [626, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [643, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [669, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], [ - 622, + 688, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, + "lhs": { "Deref": { "register": "AP", "offset": -1 } }, "rhs": { "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" }, - "dst": { - "register": "AP", - "offset": 4 - } + "dst": { "register": "AP", "offset": 4 } } } ] ], [ - 626, + 692, [ { "LinearSplit": { - "value": { - "Deref": { - "register": "AP", - "offset": 3 - } - }, - "scalar": { - "Immediate": "0x110000000000000000" - }, - "max_x": { - "Immediate": "0xffffffffffffffffffffffffffffffff" - }, - "x": { - "register": "AP", - "offset": -2 - }, - "y": { - "register": "AP", - "offset": -1 - } + "value": { "Deref": { "register": "AP", "offset": 3 } }, + "scalar": { "Immediate": "0x110000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -2 }, + "y": { "register": "AP", "offset": -1 } } } ] ], [ - 636, + 702, [ { "LinearSplit": { - "value": { - "Deref": { - "register": "AP", - "offset": -2 - } - }, - "scalar": { - "Immediate": "0x8000000000000000000000000000000" - }, - "max_x": { - "Immediate": "0xffffffffffffffffffffffffffffffff" - }, - "x": { - "register": "AP", - "offset": -1 - }, - "y": { - "register": "AP", - "offset": 0 - } + "value": { "Deref": { "register": "AP", "offset": -2 } }, + "scalar": { "Immediate": "0x8000000000000000000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -1 }, + "y": { "register": "AP", "offset": 0 } } } ] ], + [710, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], [ - 644, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 668, + 732, [ { "SystemCall": { - "system": { - "Deref": { - "register": "FP", - "offset": -10 - } - } + "system": { "Deref": { "register": "FP", "offset": -8 } } } } ] ], [ - 681, + 745, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -6 - } - }, - "rhs": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Deref": { "register": "AP", "offset": -6 } }, + "rhs": { "Deref": { "register": "AP", "offset": -1 } }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 693, + 757, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Deref": { "register": "AP", "offset": -1 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 695, + 759, [ { "DivMod": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -2 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 3 - }, - "remainder": { - "register": "AP", - "offset": 4 - } + "lhs": { "Deref": { "register": "AP", "offset": -2 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "quotient": { "register": "AP", "offset": 3 }, + "remainder": { "register": "AP", "offset": 4 } } } ] ], [ - 719, + 783, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -2 - } - }, - "rhs": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Deref": { "register": "AP", "offset": -2 } }, + "rhs": { "Deref": { "register": "AP", "offset": -1 } }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 731, + 795, [ { "TestLessThan": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Deref": { "register": "AP", "offset": -1 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": 0 } } } ] ], [ - 733, + 797, [ { "DivMod": { - "lhs": { - "Deref": { - "register": "AP", - "offset": -2 - } - }, - "rhs": { - "Immediate": "0x100000000000000000000000000000000" - }, - "quotient": { - "register": "AP", - "offset": 3 - }, - "remainder": { - "register": "AP", - "offset": 4 - } - } - } - ] - ], - [ - 765, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 782, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 799, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 816, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } + "lhs": { "Deref": { "register": "AP", "offset": -2 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "quotient": { "register": "AP", "offset": 3 }, + "remainder": { "register": "AP", "offset": 4 } } } ] ], - [ - 844, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ] + [829, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [846, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [863, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [880, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [908, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]] ], "pythonic_hints": [ + [0, ["memory[ap + 0] = 2320 <= memory[fp + -6]"]], + [40, ["memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296"]], [ - 0, - [ - "memory[ap + 0] = 5540 <= memory[fp + -6]" - ] - ], - [ - 89, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 108, + 44, [ - "memory[ap + 0] = 2570 <= memory[ap + -100]" + "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" ] ], + [86, ["memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296"]], [ - 138, + 90, [ - "memory[ap + 0] = segments.add()" + "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" ] ], + [136, ["memory[ap + 0] = segments.add()"]], + [155, ["memory[ap + 0] = 2570 <= memory[ap + -71]"]], + [184, ["memory[ap + 0] = segments.add()"]], + [205, ["memory[ap + 0] = segments.add()"]], + [220, ["memory[ap + 0] = segments.add()"]], + [241, ["memory[ap + 0] = segments.add()"]], + [262, ["memory[ap + 0] = segments.add()"]], + [276, ["memory[ap + 0] = segments.add()"]], + [290, ["memory[ap + 0] = segments.add()"]], + [486, ["memory[ap + 0] = 24170 <= memory[fp + -11]"]], + [497, ["memory[ap + -1] = memory[ap + 0] < 4294967296"]], [ - 159, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 174, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 188, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 384, - [ - "memory[ap + 0] = 25240 <= memory[fp + -11]" - ] - ], - [ - 397, - [ - "memory[ap + -1] = memory[ap + 0] < 4294967296" - ] - ], - [ - 417, - [ - "memory[ap + 0] = (memory[ap + -1] + memory[fp + -9]) % PRIME < 4294967296" - ] - ], - [ - 447, + 530, [ "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" ] ], [ - 470, + 553, [ "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" ] ], [ - 490, + 573, [ "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" ] ], [ - 517, + 600, [ "memory[ap + 0] = (memory[fp + -9] + memory[ap + -1]) % PRIME < 4294967296" ] ], + [626, ["memory[ap + 0] = segments.add()"]], + [643, ["memory[ap + 0] = segments.add()"]], + [669, ["memory[ap + 0] = segments.add()"]], [ - 543, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 560, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 586, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 603, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 622, + 688, [ "memory[ap + 4] = memory[ap + -1] < 3618502788666131106986593281521497120414687020801267626233049500247285301248" ] ], [ - 626, + 692, [ "\n(value, scalar) = (memory[ap + 3], 313594649253062377472)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -2] = x\nmemory[ap + -1] = y\n" ] ], [ - 636, + 702, [ "\n(value, scalar) = (memory[ap + -2], 10633823966279326983230456482242756608)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -1] = x\nmemory[ap + 0] = y\n" ] ], + [710, ["memory[ap + 0] = segments.add()"]], + [732, ["syscall_handler.syscall(syscall_ptr=memory[fp + -8])"]], + [745, ["memory[ap + 0] = memory[ap + -6] < memory[ap + -1]"]], [ - 644, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 668, - [ - "syscall_handler.syscall(syscall_ptr=memory[fp + -10])" - ] - ], - [ - 681, - [ - "memory[ap + 0] = memory[ap + -6] < memory[ap + -1]" - ] - ], - [ - 693, + 757, [ "memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456" ] ], [ - 695, + 759, [ "(memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456)" ] ], + [783, ["memory[ap + 0] = memory[ap + -2] < memory[ap + -1]"]], [ - 719, - [ - "memory[ap + 0] = memory[ap + -2] < memory[ap + -1]" - ] - ], - [ - 731, + 795, [ "memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456" ] ], [ - 733, + 797, [ "(memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456)" ] ], - [ - 765, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 782, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 799, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 816, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 844, - [ - "memory[ap + 0] = segments.add()" - ] - ] + [829, ["memory[ap + 0] = segments.add()"]], + [846, ["memory[ap + 0] = segments.add()"]], + [863, ["memory[ap + 0] = segments.add()"]], + [880, ["memory[ap + 0] = segments.add()"]], + [908, ["memory[ap + 0] = segments.add()"]] ], "entry_points_by_type": { "EXTERNAL": [ { "selector": "0xe2054f8a912367e38a22ce773328ff8aabf8082c4120bad9ef085e1dbf29a7", "offset": 0, - "builtins": [ - "range_check" - ] + "builtins": ["range_check"] } ], "L1_HANDLER": [], "CONSTRUCTOR": [] } -} \ No newline at end of file +} diff --git a/crates/pre-processor/src/compile/config.rs b/crates/pre-processor/src/compile/config.rs new file mode 100644 index 00000000..aaee16e7 --- /dev/null +++ b/crates/pre-processor/src/compile/config.rs @@ -0,0 +1,29 @@ +use std::path::PathBuf; + +use hdp_primitives::constant::DEFAULT_DRY_CAIRO_RUN_CAIRO_FILE; +use hdp_provider::evm::config::EvmProviderConfig; + +pub struct CompilerConfig { + // dry-run program path + pub dry_run_program_path: PathBuf, + pub provider_config: EvmProviderConfig, +} + +impl CompilerConfig { + pub fn with_dry_run_program_path(self, dry_run_program_path: PathBuf) -> Self { + Self { + dry_run_program_path, + provider_config: self.provider_config, + } + } +} + +impl Default for CompilerConfig { + fn default() -> Self { + let default_provider_config = EvmProviderConfig::default(); + CompilerConfig { + dry_run_program_path: PathBuf::from(DEFAULT_DRY_CAIRO_RUN_CAIRO_FILE), + provider_config: default_provider_config, + } + } +} diff --git a/crates/pre-processor/src/compile/datalake/fetchable/block_sampled.rs b/crates/pre-processor/src/compile/datalake/fetchable/block_sampled.rs index 07ff4821..256e9a56 100644 --- a/crates/pre-processor/src/compile/datalake/fetchable/block_sampled.rs +++ b/crates/pre-processor/src/compile/datalake/fetchable/block_sampled.rs @@ -1,7 +1,7 @@ use hdp_primitives::{ block::account::Account, processed_types::{ - account::ProcessedAccount, header::ProcessedHeader, mmr::MMRMeta, mpt::ProcessedMPTProof, + account::ProcessedAccount, header::ProcessedHeader, mpt::ProcessedMPTProof, storage::ProcessedStorage, }, task::datalake::{ @@ -22,14 +22,13 @@ impl Fetchable for BlockSampledDatalake { async fn fetch(&self, provider: EvmProvider) -> Result { let mut aggregation_set: Vec = Vec::new(); - let (mmr_meta, headers_proofs) = provider + let (mmr_metas, headers_proofs) = provider .get_range_of_header_proofs( self.block_range_start, self.block_range_end, self.increment, ) .await?; - let mmr_meta = MMRMeta::from(mmr_meta); let mut headers: HashSet = HashSet::new(); let mut accounts: HashSet = HashSet::new(); let mut storages: HashSet = HashSet::new(); @@ -132,7 +131,7 @@ impl Fetchable for BlockSampledDatalake { storages, transactions: HashSet::new(), transaction_receipts: HashSet::new(), - mmr_meta, + mmr_metas, }) } } diff --git a/crates/pre-processor/src/compile/datalake/fetchable/mod.rs b/crates/pre-processor/src/compile/datalake/fetchable/mod.rs index 48bf9e09..d36e3ab5 100644 --- a/crates/pre-processor/src/compile/datalake/fetchable/mod.rs +++ b/crates/pre-processor/src/compile/datalake/fetchable/mod.rs @@ -39,5 +39,5 @@ pub struct FetchedDatalake { /// Transaction receipts related to the datalake pub transaction_receipts: HashSet, /// MMR meta data related to the headers - pub mmr_meta: MMRMeta, + pub mmr_metas: HashSet, } diff --git a/crates/pre-processor/src/compile/datalake/fetchable/transactions.rs b/crates/pre-processor/src/compile/datalake/fetchable/transactions.rs index f5437a34..201f9975 100644 --- a/crates/pre-processor/src/compile/datalake/fetchable/transactions.rs +++ b/crates/pre-processor/src/compile/datalake/fetchable/transactions.rs @@ -2,8 +2,7 @@ use alloy::primitives::U256; use anyhow::Result; use hdp_primitives::{ processed_types::{ - header::ProcessedHeader, mmr::MMRMeta, receipt::ProcessedReceipt, - transaction::ProcessedTransaction, + header::ProcessedHeader, receipt::ProcessedReceipt, transaction::ProcessedTransaction, }, task::datalake::{ transactions::{TransactionsCollection, TransactionsInBlockDatalake}, @@ -20,10 +19,10 @@ impl Fetchable for TransactionsInBlockDatalake { async fn fetch(&self, provider: EvmProvider) -> Result { let mut aggregation_set: Vec = Vec::new(); - let (mmr_meta, headers_proofs) = provider + let (mmr_metas, headers_proofs) = provider .get_range_of_header_proofs(self.target_block, self.target_block, self.increment) .await?; - let mmr_meta = MMRMeta::from(mmr_meta); + let mut headers: HashSet = HashSet::new(); let mut transactions: HashSet = HashSet::new(); let mut transaction_receipts: HashSet = HashSet::new(); @@ -91,7 +90,7 @@ impl Fetchable for TransactionsInBlockDatalake { storages: HashSet::new(), transactions, transaction_receipts, - mmr_meta, + mmr_metas, }) } } diff --git a/crates/pre-processor/src/compile/datalake/mod.rs b/crates/pre-processor/src/compile/datalake/mod.rs index 6724f235..505ffadb 100644 --- a/crates/pre-processor/src/compile/datalake/mod.rs +++ b/crates/pre-processor/src/compile/datalake/mod.rs @@ -1,93 +1,206 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use crate::compile::datalake::fetchable::Fetchable; use hdp_primitives::{ - processed_types::{ - account::ProcessedAccount, header::ProcessedHeader, receipt::ProcessedReceipt, - storage::ProcessedStorage, transaction::ProcessedTransaction, - }, solidity_types::traits::DatalakeComputeCodecs, task::datalake::{envelope::DatalakeEnvelope, DatalakeCompute}, }; use hdp_provider::evm::provider::EvmProvider; +use tracing::info; -use super::{Compilable, CompilationResults, CompileConfig, CompileError}; +use super::{config::CompilerConfig, Compilable, CompilationResult, CompileError}; pub mod fetchable; -impl Compilable for Vec { +impl Compilable for DatalakeCompute { async fn compile( &self, - compile_config: &CompileConfig, - ) -> Result { - let mut commit_results_maps = HashMap::new(); - let mut headers: HashSet = HashSet::new(); - let mut accounts: HashSet = HashSet::new(); - let mut storages: HashSet = HashSet::new(); - let mut transactions: HashSet = HashSet::new(); - let mut transaction_receipts: HashSet = HashSet::new(); - let mut mmr = None; - let mut pre_processable = true; + compile_config: &CompilerConfig, + ) -> Result { + info!("target task: {:#?}", self); + let task_commitment = self.commit(); + let aggregation_fn = &self.compute.aggregate_fn_id; + let fn_context = &self.compute.aggregate_fn_ctx; + let provider = EvmProvider::new(compile_config.provider_config.clone()); + match self.datalake { + DatalakeEnvelope::BlockSampled(ref datalake) => { + let compiled_block_sampled = datalake.fetch(provider).await?; + let aggregated_result = aggregation_fn + .operation(&compiled_block_sampled.values, Some(fn_context.clone()))?; + Ok(CompilationResult::new( + aggregation_fn.is_pre_processable(), + vec![(task_commitment, aggregated_result)] + .into_iter() + .collect(), + compiled_block_sampled.headers, + compiled_block_sampled.accounts, + compiled_block_sampled.storages, + HashSet::new(), + HashSet::new(), + compiled_block_sampled.mmr_metas, + )) + } + DatalakeEnvelope::Transactions(ref datalake) => { + let compiled_tx_datalake = datalake.fetch(provider).await?; + let aggregated_result = aggregation_fn + .operation(&compiled_tx_datalake.values, Some(fn_context.clone()))?; + Ok(CompilationResult::new( + aggregation_fn.is_pre_processable(), + vec![(task_commitment, aggregated_result)] + .into_iter() + .collect(), + compiled_tx_datalake.headers, + HashSet::new(), + HashSet::new(), + compiled_tx_datalake.transactions, + compiled_tx_datalake.transaction_receipts, + compiled_tx_datalake.mmr_metas, + )) + } + } + } +} + +pub type DatalakeComputeVec = Vec; + +impl Compilable for DatalakeComputeVec { + async fn compile( + &self, + compile_config: &CompilerConfig, + ) -> Result { + let mut final_results = CompilationResult::default(); for datalake_compute in self { - let task_commitment = datalake_compute.commit(); - let aggregation_fn = &datalake_compute.compute.aggregate_fn_id; - let fn_context = datalake_compute.compute.aggregate_fn_ctx.clone(); - let provider = EvmProvider::new(compile_config.provider.clone()); - match datalake_compute.datalake { - DatalakeEnvelope::BlockSampled(ref datalake) => { - let compiled_block_sampled = datalake.fetch(provider).await?; - headers.extend(compiled_block_sampled.headers); - accounts.extend(compiled_block_sampled.accounts); - storages.extend(compiled_block_sampled.storages); - if mmr.is_some() && mmr.unwrap() != compiled_block_sampled.mmr_meta { - return Err(CompileError::InvalidMMR); - } else { - mmr = Some(compiled_block_sampled.mmr_meta); - } - - // Compute datalake over specified aggregation function to validate - let aggregated_result = aggregation_fn - .operation(&compiled_block_sampled.values, Some(fn_context))?; - // Save the datalake results - commit_results_maps.insert(task_commitment, aggregated_result); - if !aggregation_fn.is_pre_processable() { - pre_processable = false; - } - } - DatalakeEnvelope::Transactions(ref datalake) => { - let compiled_tx_datalake = datalake.fetch(provider).await?; - headers.extend(compiled_tx_datalake.headers); - transactions.extend(compiled_tx_datalake.transactions); - transaction_receipts.extend(compiled_tx_datalake.transaction_receipts); - - if mmr.is_some() && mmr.unwrap() != compiled_tx_datalake.mmr_meta { - return Err(CompileError::InvalidMMR); - } else { - mmr = Some(compiled_tx_datalake.mmr_meta); - } - - // Compute datalake over specified aggregation function to validate - let aggregated_result = - aggregation_fn.operation(&compiled_tx_datalake.values, Some(fn_context))?; - // Save the datalake results - commit_results_maps.insert(task_commitment, aggregated_result); - if !aggregation_fn.is_pre_processable() { - pre_processable = false; - } - } - }; + let current_results = datalake_compute.compile(compile_config).await?; + final_results.extend(current_results); } - Ok(CompilationResults::new( - pre_processable, - commit_results_maps, - headers, - accounts, - storages, - transactions, - transaction_receipts, - mmr.unwrap(), - )) + Ok(final_results) + } +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use alloy::primitives::{address, B256, U256}; + use hdp_primitives::{ + aggregate_fn::AggregationFunction, + task::datalake::{ + block_sampled::{ + AccountField, BlockSampledCollection, BlockSampledDatalake, HeaderField, + }, + compute::Computation, + transactions::{ + IncludedTypes, TransactionField, TransactionReceiptField, TransactionsCollection, + TransactionsInBlockDatalake, + }, + }, + }; + + use super::*; + + #[tokio::test] + async fn test_compile_block_sampled_datalake_compute_vec() { + let program_path = "../../build/compiled_cairo/contract_dry_run.json"; + + let datalake_compute_vec = vec![ + DatalakeCompute { + compute: Computation::new(AggregationFunction::MIN, None), + datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { + block_range_start: 10001, + block_range_end: 10005, + increment: 1, + sampled_property: BlockSampledCollection::Header(HeaderField::Number), + }), + }, + DatalakeCompute { + compute: Computation::new(AggregationFunction::AVG, None), + datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { + block_range_start: 6127485, + block_range_end: 6127495, + increment: 1, + sampled_property: BlockSampledCollection::Account( + address!("7f2c6f930306d3aa736b3a6c6a98f512f74036d4"), + AccountField::Balance, + ), + }), + }, + DatalakeCompute { + compute: Computation::new(AggregationFunction::AVG, None), + datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { + block_range_start: 6127485, + block_range_end: 6127490, + increment: 1, + sampled_property: BlockSampledCollection::Storage( + address!("75CeC1db9dCeb703200EAa6595f66885C962B920"), + B256::from(U256::from(1)), + ), + }), + }, + ]; + + let compiler_config = + CompilerConfig::default().with_dry_run_program_path(PathBuf::from(program_path)); + + let results = datalake_compute_vec + .compile(&compiler_config) + .await + .unwrap(); + assert_eq!(results.headers.len(), 16); + assert_eq!(results.accounts.len(), 2); + assert_eq!(results.storages.len(), 1); + let storage_proofs = results.storages.iter().next().unwrap(); + assert_eq!(storage_proofs.proofs.len(), 6); + assert_eq!(results.transactions.len(), 0); + assert_eq!(results.transaction_receipts.len(), 0); + assert_eq!(results.mmr_metas.len(), 1); + } + + #[tokio::test] + async fn test_compile_transactions_datalake_compute_vec() { + let program_path = "../../build/compiled_cairo/contract_dry_run.json"; + + let datalake_compute_vec = vec![ + DatalakeCompute { + compute: Computation::new(AggregationFunction::MIN, None), + datalake: DatalakeEnvelope::Transactions(TransactionsInBlockDatalake { + target_block: 6127486, + start_index: 0, + end_index: 10, + increment: 1, + included_types: IncludedTypes::from(&[1, 1, 1, 1]), + sampled_property: TransactionsCollection::Transactions( + TransactionField::GasLimit, + ), + }), + }, + DatalakeCompute { + compute: Computation::new(AggregationFunction::MIN, None), + datalake: DatalakeEnvelope::Transactions(TransactionsInBlockDatalake { + target_block: 6127485, + start_index: 0, + end_index: 11, + increment: 1, + included_types: IncludedTypes::from(&[1, 1, 1, 1]), + sampled_property: TransactionsCollection::TranasactionReceipts( + TransactionReceiptField::Success, + ), + }), + }, + ]; + + let compiler_config = + CompilerConfig::default().with_dry_run_program_path(PathBuf::from(program_path)); + let results = datalake_compute_vec + .compile(&compiler_config) + .await + .unwrap(); + assert_eq!(results.headers.len(), 2); + assert_eq!(results.accounts.len(), 0); + assert_eq!(results.storages.len(), 0); + assert_eq!(results.transactions.len(), 10); + assert_eq!(results.transaction_receipts.len(), 11); + assert_eq!(results.mmr_metas.len(), 1); } } diff --git a/crates/pre-processor/src/compile/mod.rs b/crates/pre-processor/src/compile/mod.rs index 5d857b39..02fc9436 100644 --- a/crates/pre-processor/src/compile/mod.rs +++ b/crates/pre-processor/src/compile/mod.rs @@ -1,20 +1,26 @@ use alloy::primitives::{B256, U256}; + +use config::CompilerConfig; use hdp_primitives::processed_types::{ account::ProcessedAccount, header::ProcessedHeader, mmr::MMRMeta, receipt::ProcessedReceipt, storage::ProcessedStorage, transaction::ProcessedTransaction, }; -use hdp_provider::evm::provider::EvmProviderConfig; -use module::ModuleCompilerConfig; + use std::collections::{HashMap, HashSet}; use thiserror::Error; use crate::module_registry::ModuleRegistryError; +pub mod config; pub mod datalake; pub mod module; +pub mod task; #[derive(Error, Debug)] pub enum CompileError { + #[error("Class hash mismatch")] + ClassHashMismatch, + #[error("Cairo Runner Error: {0}")] CairoRunnerError(#[from] hdp_cairo_runner::CairoRunnerError), @@ -32,23 +38,21 @@ pub enum CompileError { #[error("Error from module registry: {0}")] ModuleRegistryError(#[from] ModuleRegistryError), -} -pub struct CompileConfig { - pub provider: EvmProviderConfig, - pub module: ModuleCompilerConfig, + #[error("Compilation failed")] + CompilationFailed, } /// Compile vector of tasks into compilation results pub trait Compilable { fn compile( &self, - compile_config: &CompileConfig, - ) -> impl std::future::Future> + Send; + compile_config: &CompilerConfig, + ) -> impl std::future::Future> + Send; } -#[derive(Debug)] -pub struct CompilationResults { +#[derive(Debug, PartialEq)] +pub struct CompilationResult { /// flag to check if the aggregation function is pre-processable pub pre_processable: bool, /// task_commitment -> value @@ -64,17 +68,32 @@ pub struct CompilationResults { /// Transaction receipts related to the datalake pub transaction_receipts: HashSet, /// MMR meta data related to the headers - pub mmr_meta: MMRMeta, + pub mmr_metas: HashSet, +} + +impl Default for CompilationResult { + fn default() -> Self { + Self { + pre_processable: true, + commit_results_maps: HashMap::new(), + headers: HashSet::new(), + accounts: HashSet::new(), + storages: HashSet::new(), + transactions: HashSet::new(), + transaction_receipts: HashSet::new(), + mmr_metas: HashSet::new(), + } + } } -impl CompilationResults { +impl CompilationResult { pub fn new_without_result( headers: HashSet, accounts: HashSet, storages: HashSet, transactions: HashSet, transaction_receipts: HashSet, - mmr_meta: MMRMeta, + mmr_metas: HashSet, ) -> Self { Self { pre_processable: false, @@ -84,7 +103,7 @@ impl CompilationResults { storages, transactions, transaction_receipts, - mmr_meta, + mmr_metas, } } @@ -97,7 +116,7 @@ impl CompilationResults { storages: HashSet, transactions: HashSet, transaction_receipts: HashSet, - mmr_meta: MMRMeta, + mmr_metas: HashSet, ) -> Self { Self { pre_processable, @@ -107,7 +126,23 @@ impl CompilationResults { storages, transactions, transaction_receipts, - mmr_meta, + mmr_metas, + } + } + + /// Extend the current compilation results with another compilation results + pub fn extend(&mut self, other: CompilationResult) { + self.headers.extend(other.headers); + self.accounts.extend(other.accounts); + self.storages.extend(other.storages); + self.transactions.extend(other.transactions); + self.transaction_receipts.extend(other.transaction_receipts); + self.commit_results_maps.extend(other.commit_results_maps); + self.mmr_metas.extend(other.mmr_metas); + + // if any of the task is not pre-processable, the whole batch is not pre-processable + if !(self.pre_processable && other.pre_processable) { + self.pre_processable = false; } } } diff --git a/crates/pre-processor/src/compile/module.rs b/crates/pre-processor/src/compile/module.rs index 75a8a5d3..3e976474 100644 --- a/crates/pre-processor/src/compile/module.rs +++ b/crates/pre-processor/src/compile/module.rs @@ -1,60 +1,60 @@ -//! THIS IS WIP, NOT READY FOR USE //! Preprocessor is reponsible for identifying the required values. //! This will be most abstract layer of the preprocessor. -#![allow(dead_code)] - use core::panic; -use std::path::PathBuf; -use std::sync::Arc; - -use crate::{module_registry::ModuleRegistry, ExtendedModule}; - -use alloy::primitives::ChainId; +use hdp_cairo_runner::dry_run::DryRunResult; use hdp_cairo_runner::{cairo_dry_run, input::dry_run::DryRunnerProgramInput}; -use hdp_primitives::constant::DRY_RUN_OUTPUT_FILE; -use hdp_primitives::{processed_types::module::ProcessedModule, task::module::Module}; -use hdp_provider::{evm::provider::EvmProvider, key::FetchKeyEnvelope}; -use starknet::providers::Url; +use hdp_primitives::constant::DRY_CAIRO_RUN_OUTPUT_FILE; +use hdp_primitives::processed_types::cairo_format; +use hdp_primitives::task::ExtendedModule; +use hdp_provider::evm::from_keys::categorize_fetch_keys; +use hdp_provider::evm::provider::EvmProvider; +use std::collections::HashMap; +use std::path::PathBuf; use tracing::info; -use super::{Compilable, CompilationResults, CompileConfig, CompileError}; - -pub type BatchedModule = Vec; +use super::config::CompilerConfig; +use super::{Compilable, CompilationResult, CompileError}; -pub struct ModuleCompilerConfig { - // rpc url to fetch the module class from starknet - pub module_registry_rpc_url: Url, - // pre-run program path - pub program_path: PathBuf, -} +pub type ModuleVec = Vec; -impl Compilable for BatchedModule { +impl Compilable for ModuleVec { async fn compile( &self, - compile_config: &CompileConfig, - ) -> Result { - // 0. initialize the module registry and provider - let rpc_url = compile_config.module.module_registry_rpc_url.clone(); - let program_path = compile_config.module.program_path.clone(); - let module_registry = ModuleRegistry::new(rpc_url); - - // 1. generate input data required for dry run - info!("1. Generating input data for dry run..."); - let arc_module_registry = Arc::new(module_registry); - let extended_modules = arc_module_registry - .get_multiple_module_classes(self.clone()) - .await?; - let input = generate_input(extended_modules, PathBuf::from(DRY_RUN_OUTPUT_FILE)).await?; + compile_config: &CompilerConfig, + ) -> Result { + info!("target task: {:#?}", self[0].task); + let dry_run_program_path = compile_config.dry_run_program_path.clone(); + let tasks_commitments = self + .iter() + .map(|module| module.task.commit()) + .collect::>(); + + let input = generate_input(self.to_vec(), PathBuf::from(DRY_CAIRO_RUN_OUTPUT_FILE)).await?; let input_string = serde_json::to_string_pretty(&input).expect("Failed to serialize module class"); // 2. run the dry run and get the fetch points info!("2. Running dry-run... "); - let keys: Vec = cairo_dry_run(program_path, input_string)?; + let keys: DryRunResult = cairo_dry_run(dry_run_program_path, input_string)?; + + if keys[0].class_hash != self[0].task.class_hash { + return Err(CompileError::ClassHashMismatch); + } + + if keys.len() != 1 { + // TODO: temporary solution. Need to handle multiple module in future + panic!("Multiple Modules are not supported yet"); + } + let dry_runned_module = keys.into_iter().next().unwrap(); + let mut commit_results_maps = HashMap::new(); + commit_results_maps.insert( + tasks_commitments[0], + dry_runned_module.result.to_combined_string().into(), + ); // 3. call provider using keys - let keys_maps_chain = categrize_fetch_keys_by_chain_id(keys); + let keys_maps_chain = categorize_fetch_keys(dry_runned_module.fetch_keys); if keys_maps_chain.len() > 1 { // TODO: This is temporary solution. Need to handle multiple chain id in future panic!("Multiple chain id is not supported yet"); @@ -66,36 +66,22 @@ impl Compilable for BatchedModule { // This config cannot handle the situation when calling multiple chain data in one module // But as this have not used, for now we can just follow batch's chain id info!("3. Fetching proofs from provider..."); - let provider = EvmProvider::new(compile_config.provider.clone()); - let results = provider - .fetch_proofs_from_keys(keys.into_iter().collect()) - .await?; + let provider = EvmProvider::new(compile_config.provider_config.clone()); + let results = provider.fetch_proofs_from_keys(keys).await?; - Ok(CompilationResults::new_without_result( + Ok(CompilationResult::new( + true, + commit_results_maps, results.headers.into_iter().collect(), results.accounts.into_iter().collect(), results.storages.into_iter().collect(), results.transactions.into_iter().collect(), results.transaction_receipts.into_iter().collect(), - results.mmr_meta, + results.mmr_metas.into_iter().collect(), )) } } -/// Categorize fetch keys by chain id -/// This is require to initiate multiple provider for different chain id -fn categrize_fetch_keys_by_chain_id( - fetch_keys: Vec, -) -> Vec<(ChainId, Vec)> { - let mut chain_id_map = std::collections::HashMap::new(); - for key in fetch_keys { - let chain_id = key.get_chain_id(); - let keys = chain_id_map.entry(chain_id).or_insert_with(Vec::new); - keys.push(key); - } - chain_id_map.into_iter().collect() -} - /// Generate input structure for preprocessor that need to pass to runner async fn generate_input( extended_modules: Vec, @@ -104,7 +90,8 @@ async fn generate_input( // Collect results, filter out any errors let mut collected_results = Vec::new(); for module in extended_modules { - let input_module = ProcessedModule::new(module.task.inputs, module.module_class); + let input_module = + cairo_format::ProcessedModule::new(module.task.inputs, module.module_class); collected_results.push(input_module); } @@ -113,49 +100,3 @@ async fn generate_input( collected_results, )) } - -#[cfg(test)] -mod tests { - use hdp_primitives::task::module::ModuleTag; - use hdp_provider::evm::provider::EvmProviderConfig; - use starknet::macros::felt; - - use super::*; - const SEPOLIA_RPC_URL: &str = - "https://eth-sepolia.g.alchemy.com/v2/xar76cftwEtqTBWdF4ZFy9n8FLHAETDv"; - const SN_SEPOLIA_RPC_URL: &str = - "https://starknet-sepolia.g.alchemy.com/v2/lINonYKIlp4NH9ZI6wvqJ4HeZj7T4Wm6"; - - #[ignore = "ignore for now"] - #[tokio::test] - async fn test_compile_module() { - let program_path = "../../build/compiled_cairo/contract_dry_run.json"; - - let module = Module::from_tag( - ModuleTag::AccountBalanceExample, - vec![felt!("1"), felt!("0")], - ); - - let module_config = ModuleCompilerConfig { - module_registry_rpc_url: Url::parse(SN_SEPOLIA_RPC_URL).unwrap(), - program_path: PathBuf::from(program_path), - }; - - let provider_config = EvmProviderConfig { - rpc_url: Url::parse(SEPOLIA_RPC_URL).unwrap(), - chain_id: 11155111, - max_requests: 100, - }; - let compiled_result: CompilationResults = vec![module.clone()] - .compile(&CompileConfig { - provider: provider_config, - module: module_config, - }) - .await - .unwrap(); - assert_eq!(compiled_result.headers.len(), 10); - assert_eq!(compiled_result.accounts.len(), 1); - let account = compiled_result.accounts.iter().next().unwrap(); - assert_eq!(account.proofs.len(), 10); - } -} diff --git a/crates/pre-processor/src/compile/task.rs b/crates/pre-processor/src/compile/task.rs new file mode 100644 index 00000000..dae0e074 --- /dev/null +++ b/crates/pre-processor/src/compile/task.rs @@ -0,0 +1,29 @@ +use hdp_primitives::task::TaskEnvelope; + +use super::{config::CompilerConfig, Compilable, CompilationResult, CompileError}; + +impl Compilable for Vec { + async fn compile( + &self, + compile_config: &CompilerConfig, + ) -> Result { + let (datalakes, modules) = TaskEnvelope::divide_tasks(self.to_vec()); + let mut compiled_result = if !datalakes.is_empty() { + datalakes.compile(compile_config).await? + } else { + CompilationResult::default() + }; + + let module_compile_result = if !modules.is_empty() { + modules.compile(compile_config).await? + } else { + CompilationResult::default() + }; + compiled_result.extend(module_compile_result); + if compiled_result == CompilationResult::default() { + Err(CompileError::CompilationFailed) + } else { + Ok(compiled_result) + } + } +} diff --git a/crates/pre-processor/src/lib.rs b/crates/pre-processor/src/lib.rs index 7b4e3058..9120d922 100644 --- a/crates/pre-processor/src/lib.rs +++ b/crates/pre-processor/src/lib.rs @@ -1,25 +1,22 @@ -//! THIS IS WIP, NOT READY FOR USE //! Preprocessor is reponsible for identifying the required values. //! This will be most abstract layer of the preprocessor. use alloy::dyn_abi::DynSolValue; use alloy::primitives::{Bytes, Keccak256, B256, U256}; use alloy_merkle_tree::standard_binary_tree::StandardMerkleTree; -use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; -use compile::{Compilable, CompilationResults, CompileConfig, CompileError}; +use compile::config::CompilerConfig; +use compile::{Compilable, CompilationResult, CompileError}; +use hdp_primitives::constant::SOUND_CAIRO_RUN_OUTPUT_FILE; +use hdp_primitives::processed_types::block_proofs::ProcessedBlockProofs; use hdp_primitives::processed_types::datalake_compute::ProcessedDatalakeCompute; -use hdp_primitives::processed_types::v1_query::ProcessedResult; -use hdp_primitives::solidity_types::datalake_compute::BatchedDatalakeCompute; -use hdp_primitives::solidity_types::traits::{ - BatchedDatalakeComputeCodecs, DatalakeCodecs, DatalakeComputeCodecs, -}; -use hdp_primitives::task::datalake::DatalakeCompute; -use hdp_primitives::task::module::Module; - -use hdp_provider::key::FetchKeyEnvelope; +use hdp_primitives::processed_types::module::ProcessedModule; +use hdp_primitives::processed_types::query::ProcessorInput; +use hdp_primitives::processed_types::task::ProcessedTask; +use hdp_primitives::solidity_types::traits::{DatalakeCodecs, DatalakeComputeCodecs}; +use hdp_primitives::task::TaskEnvelope; use thiserror::Error; -use tracing::info; +use tracing::{debug, info}; pub mod compile; pub mod module_registry; @@ -35,46 +32,23 @@ pub enum PreProcessorError { } pub struct PreProcessor { - pub compile_config: CompileConfig, -} - -pub struct ExtendedDatalake { - pub task: DatalakeCompute, - pub fetch_keys_set: Vec, -} - -#[derive(Clone, Debug)] -pub struct ExtendedModule { - pub task: Module, - pub module_class: CasmContractClass, + pub compile_config: CompilerConfig, } impl PreProcessor { - pub fn new_with_config(compile_config: CompileConfig) -> Self { + pub fn new_with_config(compile_config: CompilerConfig) -> Self { Self { compile_config } } - pub async fn process_from_serialized( - &self, - batched_datalakes: Bytes, - batched_tasks: Bytes, - ) -> Result { - // 1. decode the tasks - let tasks = BatchedDatalakeCompute::decode(&batched_datalakes, &batched_tasks) - .map_err(PreProcessorError::DecodeError)?; - info!("Target tasks: {:#?}", tasks); - self.process(tasks).await - } - /// User request is pass as input of this function, /// First it will generate input structure for preprocessor that need to pass to runner /// Then it will run the preprocessor and return the result, fetch points /// Fetch points are the values that are required to run the module pub async fn process( &self, - tasks: Vec, - ) -> Result { - let task_commitments: Vec = + tasks: Vec, + ) -> Result { + let tasks_commitments: Vec = tasks.iter().map(|task| task.commit()).collect::>(); // do compile with the tasks @@ -85,96 +59,136 @@ impl PreProcessor { // do operation if possible let (tasks_merkle_tree, results_merkle_tree) = - self.build_merkle_tree(&compiled_results, task_commitments)?; + self.build_merkle_tree(&compiled_results, tasks_commitments)?; // 2. get roots of merkle tree let task_merkle_root = tasks_merkle_tree.root(); let mut combined_tasks = Vec::new(); for task in tasks { - let task_commitment = task.commit(); - let result = if results_merkle_tree.is_some() { - let compiled_result = compiled_results - .commit_results_maps - .get(&task_commitment) - .unwrap(); - let result_commitment = - self._raw_result_to_result_commitment(&task_commitment, *compiled_result); - let result_proof = results_merkle_tree - .as_ref() - .unwrap() - .get_proof(&DynSolValue::FixedBytes(result_commitment, 32)); - Some((compiled_result, result_commitment, result_proof)) - } else { - None - }; - let task_proof = - tasks_merkle_tree.get_proof(&DynSolValue::FixedBytes(task_commitment, 32)); - let encoded_task = task.encode()?; - let datalake_type = task.datalake.get_datalake_type(); - let property_type = task.datalake.get_collection_type().to_index(); + match task { + TaskEnvelope::DatalakeCompute(datalake_compute) => { + let task_commitment = datalake_compute.commit(); + let result = if results_merkle_tree.is_some() { + let compiled_result = compiled_results + .commit_results_maps + .get(&task_commitment) + .unwrap(); + let result_commitment = self + ._raw_result_to_result_commitment(&task_commitment, *compiled_result); + let result_proof = results_merkle_tree + .as_ref() + .unwrap() + .get_proof(&DynSolValue::FixedBytes(result_commitment, 32)); + Some((compiled_result, result_commitment, result_proof)) + } else { + None + }; + let task_proof = + tasks_merkle_tree.get_proof(&DynSolValue::FixedBytes(task_commitment, 32)); + let encoded_task = datalake_compute.encode()?; + let datalake_type = datalake_compute.datalake.get_datalake_type(); + let property_type = datalake_compute.datalake.get_collection_type().to_index(); + + let datalake_compute = match result { + Some(result_value) => { + let (compiled_result, result_commitment, result_proof) = result_value; + ProcessedDatalakeCompute::new_with_result( + Bytes::from(encoded_task), + task_commitment, + *compiled_result, + result_commitment, + task_proof, + result_proof, + Bytes::from(datalake_compute.datalake.encode()?), + datalake_type.into(), + property_type, + ) + } + None => ProcessedDatalakeCompute::new_without_result( + Bytes::from(encoded_task), + task_commitment, + task_proof, + Bytes::from(datalake_compute.datalake.encode()?), + datalake_type.into(), + property_type, + ), + }; - let datalake_compute = match result { - Some(result_value) => { - let (compiled_result, result_commitment, result_proof) = result_value; - ProcessedDatalakeCompute::new_with_result( - Bytes::from(encoded_task), + // wrap into ProcessedTask + let task = ProcessedTask::DatalakeCompute(datalake_compute); + combined_tasks.push(task); + } + TaskEnvelope::Module(module) => { + let task_commitment = module.task.commit(); + let compiled_result = compiled_results + .commit_results_maps + .get(&task_commitment) + .unwrap(); + let result_commitment = + self._raw_result_to_result_commitment(&task_commitment, *compiled_result); + let result_proof = results_merkle_tree + .as_ref() + .unwrap() + .get_proof(&DynSolValue::FixedBytes(result_commitment, 32)); + let task_proof = + tasks_merkle_tree.get_proof(&DynSolValue::FixedBytes(task_commitment, 32)); + let processed_module = ProcessedModule::new( task_commitment, - *compiled_result, result_commitment, task_proof, result_proof, - Bytes::from(task.datalake.encode()?), - datalake_type.into(), - property_type, - ) - } - None => ProcessedDatalakeCompute::new_without_result( - Bytes::from(encoded_task), - task_commitment, - task_proof, - Bytes::from(task.datalake.encode()?), - datalake_type.into(), - property_type, - ), - }; + module.task.inputs, + module.module_class, + ); - combined_tasks.push(datalake_compute); + let task = ProcessedTask::Module(processed_module); + combined_tasks.push(task); + } + } } - let processed_result = ProcessedResult::new( - results_merkle_tree.map(|tree| tree.root().to_string()), - task_merkle_root.to_string(), - Vec::from_iter(compiled_results.headers), - compiled_results.mmr_meta, - Vec::from_iter(compiled_results.accounts), - Vec::from_iter(compiled_results.storages), - Vec::from_iter(compiled_results.transactions), - Vec::from_iter(compiled_results.transaction_receipts), + let proofs = ProcessedBlockProofs { + mmr_metas: Vec::from_iter(compiled_results.mmr_metas), + headers: Vec::from_iter(compiled_results.headers), + accounts: Vec::from_iter(compiled_results.accounts), + storages: Vec::from_iter(compiled_results.storages), + transactions: Vec::from_iter(compiled_results.transactions), + transaction_receipts: Vec::from_iter(compiled_results.transaction_receipts), + }; + let processed_result = ProcessorInput::new( + SOUND_CAIRO_RUN_OUTPUT_FILE.into(), + results_merkle_tree.map(|tree| tree.root()), + task_merkle_root, + proofs, combined_tasks, ); - // TODO: from compiler result, generate batch for tree and final result that pass through cairo-runner - info!("Preprocessor completed successfully"); + info!("1️⃣ Preprocessor completed successfully"); Ok(processed_result) } fn build_merkle_tree( &self, - compiled_results: &CompilationResults, - task_commitments: Vec, + compiled_results: &CompilationResult, + tasks_commitments: Vec, ) -> Result<(StandardMerkleTree, Option), PreProcessorError> { let mut tasks_leaves = Vec::new(); let mut results_leaves = Vec::new(); - for task_commitment in task_commitments { + for task_commitment in tasks_commitments { if compiled_results.pre_processable { let compiled_result = match compiled_results.commit_results_maps.get(&task_commitment) { Some(result) => result, None => Err(PreProcessorError::TaskCommitmentNotFound)?, }; + debug!( + "building result merkle tree | task_commitment: {:?}, compiled_result: {:?}", + task_commitment, compiled_result + ); let result_commitment = self._raw_result_to_result_commitment(&task_commitment, *compiled_result); + debug!("result_commitment: {:?}", result_commitment); results_leaves.push(DynSolValue::FixedBytes(result_commitment, 32)); } tasks_leaves.push(DynSolValue::FixedBytes(task_commitment, 32)); @@ -200,80 +214,3 @@ impl PreProcessor { hasher.finalize() } } - -#[cfg(test)] -mod tests { - // use super::*; - // use hdp_primitives::datalake::block_sampled::{ - // BlockSampledCollection, BlockSampledDatalake, HeaderField, - // }; - // use hdp_primitives::datalake::envelope::DatalakeEnvelope; - // use hdp_primitives::datalake::task::Computation; - // use hdp_primitives::module::{Module, ModuleTag}; - // use starknet::macros::felt; - // use starknet::providers::Url; - // use std::path::PathBuf; - - // const STARKNET_SEPOLIA_RPC: &str = - // "https://starknet-sepolia.g.alchemy.com/v2/lINonYKIlp4NH9ZI6wvqJ4HeZj7T4Wm6"; - // const PREPROCESS_PROGRAM_PATH: &str = "../build/compiled_cairo/hdp.json"; - - // #[tokio::test] - // async fn test_process_only_datalake() { - // let start_process = std::time::Instant::now(); - // let config = PreProcessorConfig { - // module_registry_rpc_url: Url::parse(STARKNET_SEPOLIA_RPC).unwrap(), - // program_path: PathBuf::from("../build/compiled_cairo/hdp.json"), - // }; - // let pre_processor = PreProcessor::new_with_config(config); - - // let tasks = vec![ - // TaskEnvelope::DatalakeCompute(DatalakeCompute { - // compute: Computation::new("min", None), - // datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { - // block_range_start: 1000, - // block_range_end: 10000, - // increment: 1, - // sampled_property: BlockSampledCollection::Header(HeaderField::Number), - // }), - // }), - // TaskEnvelope::DatalakeCompute(DatalakeCompute { - // compute: Computation::new("min", None), - // datalake: DatalakeEnvelope::BlockSampled(BlockSampledDatalake { - // block_range_start: 1000, - // block_range_end: 10000, - // increment: 1, - // sampled_property: BlockSampledCollection::Header(HeaderField::Number), - // }), - // }), - // ]; - - // let result = pre_processor.process(tasks).await.unwrap(); - - // let end_process = start_process.elapsed(); - // println!("Process time: {:?}", end_process); - // assert_eq!(result.fetch_keys.len(), 9000); - // assert_eq!(result.tasks.len(), 2); - // assert!(matches!(&result.tasks[0], ExtendedTask::DatalakeCompute(_))); - // } - - // #[tokio::test] - // async fn test_process_only_module() { - // let start_process = std::time::Instant::now(); - // let config = PreProcessorConfig { - // module_registry_rpc_url: Url::parse(STARKNET_SEPOLIA_RPC).unwrap(), - // program_path: PathBuf::from(PREPROCESS_PROGRAM_PATH), - // }; - // let pre_processor = PreProcessor::new_with_config(config); - - // let module = Module::from_tag(ModuleTag::TEST, vec![felt!("1"), felt!("2")]); - // let tasks = vec![TaskEnvelope::Module(module)]; - - // let result = pre_processor.process(tasks).await.unwrap(); - // let end_process = start_process.elapsed(); - // println!("Process time: {:?}", end_process); - // assert_eq!(result.fetch_keys.len(), 0); - // assert_eq!(result.tasks.len(), 1); - // assert!(matches!(&result.tasks[0], ExtendedTask::Module(_))); - // } -} diff --git a/crates/pre-processor/src/module_registry.rs b/crates/pre-processor/src/module_registry.rs index c28bed7e..fdcfa242 100644 --- a/crates/pre-processor/src/module_registry.rs +++ b/crates/pre-processor/src/module_registry.rs @@ -5,20 +5,17 @@ use cairo_lang_starknet_classes::{ casm_contract_class::{CasmContractClass, StarknetSierraCompilationError}, contract_class::ContractClass as CairoContractClass, }; -use futures::future::join_all; -use hdp_primitives::task::module::Module; + +use hdp_primitives::task::{module::Module, ExtendedModule}; use starknet::{ core::types::{BlockId, BlockTag, ContractClass, FlattenedSierraClass}, providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider, Url}, }; use starknet_crypto::FieldElement; -use std::sync::Arc; +use std::path::PathBuf; use thiserror::Error; -use tokio::task; use tracing::info; -use crate::ExtendedModule; - #[derive(Error, Debug)] pub enum ModuleRegistryError { #[error("Serialize error: {0}")] @@ -35,6 +32,9 @@ pub enum ModuleRegistryError { #[error("Tokio join error: {0}")] TokioJoinError(#[from] tokio::task::JoinError), + + #[error("Module class source error: {0}")] + ClassSourceError(String), } pub struct ModuleRegistry { @@ -47,48 +47,85 @@ impl ModuleRegistry { Self { provider } } - pub async fn get_multiple_module_classes( - self: Arc, - modules: Vec, - ) -> Result, ModuleRegistryError> { - // Create an Arc to the ModuleRegistry to be used inside the async blocks - let module_registry: Arc = self; - - // Map each module to an asynchronous task - let module_futures: Vec<_> = modules + pub async fn get_extended_module_from_class_source_string( + &self, + class_hash: Option, + local_class_path: Option, + module_inputs: Vec, + ) -> Result { + let class_hash = + class_hash.map(|class_hash| FieldElement::from_hex_be(&class_hash).unwrap()); + let module_inputs = module_inputs .into_iter() - .map(|module| { - let module_registry = Arc::clone(&module_registry); - task::spawn(async move { - let module_hash = module.class_hash; - let module_class = module_registry.get_module_class(module_hash).await?; - Ok(ExtendedModule { - task: module, - module_class, - }) as Result - }) - }) + .map(|input| FieldElement::from_hex_be(&input).unwrap()) .collect(); + self.get_extended_module_from_class_source(class_hash, local_class_path, module_inputs) + .await + } - // Join all tasks and collect their results - let results = join_all(module_futures).await; - - // Collect results, filter out any errors - let mut collected_results = Vec::new(); - for result in results { - let module_with_class = result??; - collected_results.push(module_with_class); + pub async fn get_extended_module_from_class_source( + &self, + class_hash: Option, + local_class_path: Option, + module_inputs: Vec, + ) -> Result { + if class_hash.is_some() && local_class_path.is_some() { + return Err(ModuleRegistryError::ClassSourceError( + "Only one of class_hash or local_class_path must be provided".to_string(), + )); } - Ok(collected_results) + let casm = if let Some(ref local_class_path) = local_class_path { + self.get_module_class_from_local_path(local_class_path) + .await? + } else if let Some(class_hash) = class_hash { + self.get_module_class(class_hash).await? + } else { + return Err(ModuleRegistryError::ClassSourceError( + "One of class_hash or local_class_path must be provided".to_string(), + )); + }; + + let class_hash = casm.compiled_class_hash(); + let converted_hash = FieldElement::from_bytes_be(&class_hash.to_be_bytes()).unwrap(); + info!("Program Hash: {:#?}", converted_hash); + + let module = Module { + class_hash: converted_hash, + inputs: module_inputs, + local_class_path, + }; + + Ok(ExtendedModule { + task: module, + module_class: casm, + }) + } + + async fn get_module_class_from_local_path( + &self, + local_class_path: &PathBuf, + ) -> Result { + let casm: CasmContractClass = + serde_json::from_str(&std::fs::read_to_string(local_class_path).map_err(|_| { + ModuleRegistryError::ClassSourceError( + "Local class path is not a valid JSON file".to_string(), + ) + })?)?; + + info!( + "Contract class fetched successfully from local path: {:?}", + local_class_path + ); + Ok(casm) } - pub async fn get_module_class( + async fn get_module_class( &self, class_hash: FieldElement, ) -> Result { info!( - "Fetching contract class from module registry... Class hash: {}", + "Fetching contract class from module registry... Contract Class Hash: {:#?}", class_hash ); let contract_class = self @@ -154,7 +191,7 @@ mod tests { let module_registry = ModuleRegistry::new(url); // This is test contract class hash let class_hash = FieldElement::from_hex_be( - "0x07d6c339c3e2236d2821c1c89d4a0e9027cd6c7e491189e9694a6df7c8f10aae", + "0x02aacf92216d1ae71fbdaf3f41865c08f32317b37be18d8c136d442e94cdd823", ) .unwrap(); @@ -169,6 +206,17 @@ mod tests { assert_eq!(casm_from_rpc, ACCOUNT_BALANCE_EXAMPLE_CONTRACT.clone()); } + #[tokio::test] + async fn test_get_module_class_from_local_path() { + let (module_registry, _) = init(); + let _ = module_registry + .get_module_class_from_local_path(&PathBuf::from( + "../contracts/account_balance_example.compiled_contract_class.json", + )) + .await + .unwrap(); + } + #[tokio::test] async fn test_flattened_sierra_to_compiled_class() { let (module_registry, class_hash) = init(); @@ -187,24 +235,22 @@ mod tests { #[tokio::test] async fn test_get_multiple_module_classes() { let (module_registry, class_hash) = init(); - let module = Module { - class_hash, - inputs: vec![], - }; - let arc_registry = Arc::new(module_registry); - let extended_modules = arc_registry - .get_multiple_module_classes(vec![module.clone(), module.clone()]) + + let extended_modules = module_registry + .get_extended_module_from_class_source(Some(class_hash), None, vec![]) .await .unwrap(); - assert_eq!(extended_modules.len(), 2); - assert_eq!(extended_modules[0].task, module); + assert_eq!( - extended_modules[0].module_class, - ACCOUNT_BALANCE_EXAMPLE_CONTRACT.clone() + extended_modules.task.class_hash, + FieldElement::from_hex_be( + "0x04df21eb479ae4416fbdc00abab6fab43bff0b8083be4d1fd8602c8fbfbd2274" + ) + .unwrap() ); - assert_eq!(extended_modules[1].task, module); + assert_eq!(extended_modules.task.inputs, vec![]); assert_eq!( - extended_modules[1].module_class, + extended_modules.module_class, ACCOUNT_BALANCE_EXAMPLE_CONTRACT.clone() ); } diff --git a/crates/primitives/fixtures/mmr.json b/crates/primitives/fixtures/mmr.json index d4dd0a9b..4dd5834d 100644 --- a/crates/primitives/fixtures/mmr.json +++ b/crates/primitives/fixtures/mmr.json @@ -15,5 +15,6 @@ "0x55112088a2f7dfaf5d88ce949f3aad7c7d05d6e4eaff4053aebfbed3af885af", "0x66c82fce8bfc291095c6c9255b1f7ccf725a1e91e8ae8cd8c43ceb111c21480", "0x2e5274895f9cd556bb8dee5b2551e9cda9aa3caa23532f9824abcc62d5ad273" - ] + ], + "chain_id": 11155111 } diff --git a/crates/primitives/src/block/header.rs b/crates/primitives/src/block/header.rs index dc27ef9c..bbf0d5ab 100644 --- a/crates/primitives/src/block/header.rs +++ b/crates/primitives/src/block/header.rs @@ -7,8 +7,6 @@ use alloy::{ use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable}; use serde::{Deserialize, Serialize}; -use crate::processed_types::mmr::MMRMeta; - // ============================================================================= // Header (credit: https://github.com/paradigmxyz/reth/blob/main/crates/primitives/src/header.rs#L133) // Orignally had dependnecy on `reth_primitives` crate, but it was removed to publish in crates.io @@ -447,17 +445,6 @@ pub struct MMRMetaFromIndexer { pub mmr_size: u64, } -impl From<&MMRMetaFromIndexer> for MMRMeta { - fn from(value: &MMRMetaFromIndexer) -> Self { - Self { - id: value.mmr_id, - peaks: value.mmr_peaks.clone(), - root: value.mmr_root.to_string(), - size: value.mmr_size, - } - } -} - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct MMRProofFromIndexer { pub block_number: u64, diff --git a/crates/primitives/src/constant.rs b/crates/primitives/src/constant.rs index b1dc4e8b..065b2ba8 100644 --- a/crates/primitives/src/constant.rs +++ b/crates/primitives/src/constant.rs @@ -1,12 +1,15 @@ use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use lazy_static::lazy_static; -pub const DRY_RUN_OUTPUT_FILE: &str = "dry_run_output.json"; +pub const DRY_CAIRO_RUN_OUTPUT_FILE: &str = "dry_run_output.json"; +pub const SOUND_CAIRO_RUN_OUTPUT_FILE: &str = "cairo_run_output.json"; +pub const DEFAULT_DRY_CAIRO_RUN_CAIRO_FILE: &str = "build/compiled_cairo/contract_dry_run.json"; +pub const DEFAULT_SOUND_CAIRO_RUN_CAIRO_FILE: &str = "build/compiled_cairo/hdp.json"; lazy_static! { pub static ref ACCOUNT_BALANCE_EXAMPLE_CONTRACT: CasmContractClass = read_compiled_class_artifact(include_str!( - "../contracts/compiled/account_balance_example.json" + "../../contracts/account_balance_example.compiled_contract_class.json" )); } diff --git a/crates/primitives/src/processed_types/block_proofs.rs b/crates/primitives/src/processed_types/block_proofs.rs index 80fc697b..a0e8f406 100644 --- a/crates/primitives/src/processed_types/block_proofs.rs +++ b/crates/primitives/src/processed_types/block_proofs.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use serde::{Deserialize, Serialize}; use super::{ account::ProcessedAccount, header::ProcessedHeader, mmr::MMRMeta, receipt::ProcessedReceipt, @@ -6,9 +6,10 @@ use super::{ }; /// Provider should fetch all the proofs and rlp values from given keys. -#[derive(Serialize, Debug)] + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ProcessedBlockProofs { - pub mmr_meta: MMRMeta, + pub mmr_metas: Vec, pub headers: Vec, pub accounts: Vec, pub storages: Vec, diff --git a/crates/primitives/src/processed_types/cairo_format/block_proofs.rs b/crates/primitives/src/processed_types/cairo_format/block_proofs.rs new file mode 100644 index 00000000..2a2cce26 --- /dev/null +++ b/crates/primitives/src/processed_types/cairo_format/block_proofs.rs @@ -0,0 +1,55 @@ +use serde::Serialize; + +use crate::processed_types::{ + block_proofs::ProcessedBlockProofs as BaseProcessedBlockProofs, mmr::MMRMeta, +}; + +use super::{ + AsCairoFormat, ProcessedAccount, ProcessedHeader, ProcessedReceipt, ProcessedStorage, + ProcessedTransaction, +}; + +impl AsCairoFormat for BaseProcessedBlockProofs { + type Output = ProcessedBlockProofs; + + fn as_cairo_format(&self) -> Self::Output { + ProcessedBlockProofs { + mmr_metas: self.mmr_metas.clone(), + headers: self + .headers + .iter() + .map(|header| header.as_cairo_format()) + .collect(), + accounts: self + .accounts + .iter() + .map(|account| account.as_cairo_format()) + .collect(), + storages: self + .storages + .iter() + .map(|storage| storage.as_cairo_format()) + .collect(), + transactions: self + .transactions + .iter() + .map(|transaction| transaction.as_cairo_format()) + .collect(), + transaction_receipts: self + .transaction_receipts + .iter() + .map(|receipt| receipt.as_cairo_format()) + .collect(), + } + } +} + +#[derive(Serialize)] +pub struct ProcessedBlockProofs { + pub mmr_metas: Vec, + pub headers: Vec, + pub accounts: Vec, + pub storages: Vec, + pub transactions: Vec, + pub transaction_receipts: Vec, +} diff --git a/crates/primitives/src/processed_types/cairo_format/mod.rs b/crates/primitives/src/processed_types/cairo_format/mod.rs index 3013c735..fdd72367 100644 --- a/crates/primitives/src/processed_types/cairo_format/mod.rs +++ b/crates/primitives/src/processed_types/cairo_format/mod.rs @@ -2,26 +2,29 @@ //! Used to serialize the processed types to the Cairo Program's input format. pub mod account; +pub mod block_proofs; pub mod datalake_compute; pub mod felt_vec_unit; pub mod header; +pub mod module; pub mod mpt; +pub mod query; pub mod receipt; pub mod storage; +pub mod task; pub mod traits; pub mod transaction; -// TODO: temporary query type for first sync with original flow, will merge with new genric query later -pub mod v1_query; - pub use account::*; +pub use block_proofs::*; pub use datalake_compute::*; pub use felt_vec_unit::*; pub use header::*; +pub use module::*; pub use mpt::*; +pub use query::*; pub use receipt::*; pub use storage::*; +pub use task::*; pub use traits::*; pub use transaction::*; - -pub use v1_query::*; diff --git a/crates/primitives/src/processed_types/cairo_format/module.rs b/crates/primitives/src/processed_types/cairo_format/module.rs new file mode 100644 index 00000000..dcea28a2 --- /dev/null +++ b/crates/primitives/src/processed_types/cairo_format/module.rs @@ -0,0 +1,38 @@ +use crate::processed_types::module::ProcessedModule as BaseProcessedModule; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use starknet::core::serde::unsigned_field_element::UfeHex; +use starknet_crypto::FieldElement; + +use super::AsCairoFormat; + +impl AsCairoFormat for BaseProcessedModule { + type Output = ProcessedModule; + + fn as_cairo_format(&self) -> Self::Output { + ProcessedModule { + inputs: self.inputs.clone(), + module_class: self.module_class.clone(), + } + } +} + +#[serde_as] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ProcessedModule { + #[serde_as(as = "Vec")] + pub inputs: Vec, + /// Detail class code of the module. + /// This will be loaded to bootloader. + pub module_class: CasmContractClass, +} + +impl ProcessedModule { + pub fn new(inputs: Vec, module_class: CasmContractClass) -> Self { + ProcessedModule { + inputs, + module_class, + } + } +} diff --git a/crates/primitives/src/processed_types/cairo_format/query.rs b/crates/primitives/src/processed_types/cairo_format/query.rs new file mode 100644 index 00000000..8c6ab79b --- /dev/null +++ b/crates/primitives/src/processed_types/cairo_format/query.rs @@ -0,0 +1,40 @@ +use std::path::PathBuf; + +use crate::processed_types::query::ProcessorInput as BasedProcessorInput; +use ::serde::Serialize; +use alloy::primitives::B256; + +use super::{AsCairoFormat, ProcessedBlockProofs, ProcessedTask}; + +impl AsCairoFormat for BasedProcessorInput { + type Output = ProcessorInput; + + fn as_cairo_format(&self) -> Self::Output { + ProcessorInput { + cairo_run_output_path: self.cairo_run_output_path.clone(), + task_root: self.tasks_root, + result_root: self.results_root, + proofs: self.proofs.as_cairo_format(), + tasks: self + .tasks + .iter() + .map(|task| task.as_cairo_format()) + .collect(), + } + } +} + +#[derive(Serialize)] +pub struct ProcessorInput { + /// Path to the directory where the cairo-run output will be stored. + pub cairo_run_output_path: PathBuf, + /// Batched tasks root of all tasks. + pub task_root: B256, + /// if every tasks are pre computable, this can be Some + #[serde(skip_serializing_if = "Option::is_none")] + pub result_root: Option, + /// Fetched proofs per each fetch point. + pub proofs: ProcessedBlockProofs, + /// tasks to be executed. + pub tasks: Vec, +} diff --git a/crates/primitives/src/processed_types/cairo_format/task.rs b/crates/primitives/src/processed_types/cairo_format/task.rs new file mode 100644 index 00000000..70c26b30 --- /dev/null +++ b/crates/primitives/src/processed_types/cairo_format/task.rs @@ -0,0 +1,25 @@ +use super::{module::ProcessedModule, AsCairoFormat, ProcessedDatalakeCompute}; +use crate::processed_types::task::ProcessedTask as BaseProcessedTask; +use ::serde::Serialize; + +impl AsCairoFormat for BaseProcessedTask { + type Output = ProcessedTask; + + fn as_cairo_format(&self) -> Self::Output { + match self { + BaseProcessedTask::DatalakeCompute(datalake_compute) => { + ProcessedTask::DatalakeCompute(datalake_compute.as_cairo_format()) + } + BaseProcessedTask::Module(module) => ProcessedTask::Module(module.as_cairo_format()), + } + } +} + +#[derive(Serialize, Debug, Clone, PartialEq)] +#[serde(tag = "type", content = "context")] +pub enum ProcessedTask { + #[serde(rename = "datalake_compute")] + DatalakeCompute(ProcessedDatalakeCompute), + #[serde(rename = "module")] + Module(ProcessedModule), +} diff --git a/crates/primitives/src/processed_types/cairo_format/v1_query.rs b/crates/primitives/src/processed_types/cairo_format/v1_query.rs deleted file mode 100644 index 08dc01d0..00000000 --- a/crates/primitives/src/processed_types/cairo_format/v1_query.rs +++ /dev/null @@ -1,77 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::processed_types::{ - mmr::MMRMeta, uint256::Uint256, v1_query::ProcessedResult as BaseProcessedResult, -}; - -use super::{ - AsCairoFormat, ProcessedAccount, ProcessedDatalakeCompute, ProcessedHeader, ProcessedReceipt, - ProcessedStorage, ProcessedTransaction, -}; - -impl AsCairoFormat for BaseProcessedResult { - type Output = ProcessedResult; - - fn as_cairo_format(&self) -> ProcessedResult { - let headers = self - .headers - .iter() - .map(|header| header.as_cairo_format()) - .collect(); - let accounts = self - .accounts - .iter() - .map(|account| account.as_cairo_format()) - .collect(); - let storages = self - .storages - .iter() - .map(|storage| storage.as_cairo_format()) - .collect(); - let transactions = self - .transactions - .iter() - .map(|transaction| transaction.as_cairo_format()) - .collect(); - let transaction_receipts = self - .transaction_receipts - .iter() - .map(|receipt| receipt.as_cairo_format()) - .collect(); - let tasks = self - .tasks - .iter() - .map(|task| task.as_cairo_format()) - .collect(); - let results_root = self - .results_root - .as_ref() - .map(|root| Uint256::from_be_hex_str(root).unwrap()); - - ProcessedResult { - results_root, - tasks_root: Uint256::from_be_hex_str(&self.tasks_root).unwrap(), - headers, - mmr: self.mmr.clone(), - accounts, - storages, - transactions, - transaction_receipts, - tasks, - } - } -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct ProcessedResult { - #[serde(skip_serializing_if = "Option::is_none")] - pub results_root: Option, - pub tasks_root: Uint256, - pub headers: Vec, - pub mmr: MMRMeta, - accounts: Vec, - storages: Vec, - transactions: Vec, - transaction_receipts: Vec, - pub tasks: Vec, -} diff --git a/crates/primitives/src/processed_types/mmr.rs b/crates/primitives/src/processed_types/mmr.rs index 403f319e..a0b8fbe5 100644 --- a/crates/primitives/src/processed_types/mmr.rs +++ b/crates/primitives/src/processed_types/mmr.rs @@ -9,15 +9,17 @@ pub struct MMRMeta { pub size: u64, // hex encoded pub peaks: Vec, + pub chain_id: u64, } impl MMRMeta { - pub fn new(id: u64, root: String, size: u64, peaks: Vec) -> Self { + pub fn new(id: u64, root: String, size: u64, peaks: Vec, chain_id: u64) -> Self { MMRMeta { id, root, size, peaks, + chain_id, } } } @@ -33,13 +35,14 @@ impl From for MMRMetaFromNewIndexer { } } -impl From for MMRMeta { - fn from(val: MMRMetaFromNewIndexer) -> Self { +impl MMRMeta { + pub fn from_indexer(val: MMRMetaFromNewIndexer, chain_id: u64) -> Self { MMRMeta { id: val.mmr_id, root: val.mmr_root, size: val.mmr_size, peaks: val.mmr_peaks, + chain_id, } } } @@ -70,6 +73,7 @@ mod tests { "0x66c82fce8bfc291095c6c9255b1f7ccf725a1e91e8ae8cd8c43ceb111c21480".to_string(), "0x2e5274895f9cd556bb8dee5b2551e9cda9aa3caa23532f9824abcc62d5ad273".to_string(), ], + 11155111, ); let processed_string = fs::read_to_string("fixtures/mmr.json").unwrap(); diff --git a/crates/primitives/src/processed_types/mod.rs b/crates/primitives/src/processed_types/mod.rs index 536f5f95..baffa54c 100644 --- a/crates/primitives/src/processed_types/mod.rs +++ b/crates/primitives/src/processed_types/mod.rs @@ -1,16 +1,15 @@ pub mod cairo_format; pub mod account; +pub mod block_proofs; pub mod datalake_compute; pub mod header; pub mod mmr; pub mod module; pub mod mpt; +pub mod query; pub mod receipt; pub mod storage; +pub mod task; pub mod transaction; pub mod uint256; -// TODO: temporary query type for first sync with original flow, will merge with new genric query later -pub mod v1_query; -// TODO: will be use in v2 -pub mod block_proofs; diff --git a/crates/primitives/src/processed_types/module.rs b/crates/primitives/src/processed_types/module.rs index 7b9cb10b..7bbebd62 100644 --- a/crates/primitives/src/processed_types/module.rs +++ b/crates/primitives/src/processed_types/module.rs @@ -1,12 +1,18 @@ +use alloy::primitives::B256; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_with::serde_as; use starknet::core::serde::unsigned_field_element::UfeHex; use starknet_crypto::FieldElement; #[serde_as] -#[derive(Serialize, Clone)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ProcessedModule { + pub task_commitment: B256, + pub result_commitment: B256, + pub task_proof: Vec, + pub result_proof: Vec, + #[serde_as(as = "Vec")] pub inputs: Vec, /// Detail class code of the module. @@ -15,8 +21,19 @@ pub struct ProcessedModule { } impl ProcessedModule { - pub fn new(inputs: Vec, module_class: CasmContractClass) -> Self { + pub fn new( + task_commitment: B256, + result_commitment: B256, + task_proof: Vec, + result_proof: Vec, + inputs: Vec, + module_class: CasmContractClass, + ) -> Self { ProcessedModule { + task_commitment, + result_commitment, + task_proof, + result_proof, inputs, module_class, } diff --git a/crates/primitives/src/processed_types/query.rs b/crates/primitives/src/processed_types/query.rs new file mode 100644 index 00000000..754a902e --- /dev/null +++ b/crates/primitives/src/processed_types/query.rs @@ -0,0 +1,37 @@ +use std::path::PathBuf; + +use ::serde::{Deserialize, Serialize}; +use alloy::primitives::B256; + +use super::{block_proofs::ProcessedBlockProofs, task::ProcessedTask}; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ProcessorInput { + /// Path to the directory where the cairo-run output will be stored. + pub cairo_run_output_path: PathBuf, + // U256 type + pub tasks_root: B256, + // U256 type + #[serde(skip_serializing_if = "Option::is_none")] + pub results_root: Option, + pub proofs: ProcessedBlockProofs, + pub tasks: Vec, +} + +impl ProcessorInput { + pub fn new( + cairo_run_output_path: PathBuf, + results_root: Option, + tasks_root: B256, + proofs: ProcessedBlockProofs, + tasks: Vec, + ) -> Self { + Self { + cairo_run_output_path, + results_root, + tasks_root, + proofs, + tasks, + } + } +} diff --git a/crates/primitives/src/processed_types/task.rs b/crates/primitives/src/processed_types/task.rs new file mode 100644 index 00000000..f8a3aea5 --- /dev/null +++ b/crates/primitives/src/processed_types/task.rs @@ -0,0 +1,29 @@ +use alloy::primitives::B256; +use serde::{Deserialize, Serialize}; + +use super::{datalake_compute::ProcessedDatalakeCompute, module::ProcessedModule}; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type", content = "context")] +pub enum ProcessedTask { + #[serde(rename = "datalake_compute")] + DatalakeCompute(ProcessedDatalakeCompute), + #[serde(rename = "module")] + Module(ProcessedModule), +} + +impl ProcessedTask { + pub fn get_task_commitment(&self) -> B256 { + match self { + ProcessedTask::DatalakeCompute(datalake_compute) => datalake_compute.task_commitment, + ProcessedTask::Module(module) => module.task_commitment, + } + } + + pub fn get_task_proof(&self) -> Vec { + match self { + ProcessedTask::DatalakeCompute(datalake_compute) => datalake_compute.task_proof.clone(), + ProcessedTask::Module(module) => module.task_proof.clone(), + } + } +} diff --git a/crates/primitives/src/processed_types/v1_query.rs b/crates/primitives/src/processed_types/v1_query.rs deleted file mode 100644 index e4a7d1cf..00000000 --- a/crates/primitives/src/processed_types/v1_query.rs +++ /dev/null @@ -1,54 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use super::{ - account::ProcessedAccount, datalake_compute::ProcessedDatalakeCompute, header::ProcessedHeader, - mmr::MMRMeta, receipt::ProcessedReceipt, storage::ProcessedStorage, - transaction::ProcessedTransaction, -}; - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct ProcessedResult { - // U256 type - #[serde(skip_serializing_if = "Option::is_none")] - pub results_root: Option, - // U256 type - pub tasks_root: String, - pub headers: Vec, - pub mmr: MMRMeta, - pub accounts: Vec, - pub storages: Vec, - pub transactions: Vec, - pub transaction_receipts: Vec, - pub tasks: Vec, -} - -impl ProcessedResult { - #[allow(clippy::too_many_arguments)] - pub fn new( - results_root: Option, - tasks_root: String, - headers: Vec, - mmr: MMRMeta, - accounts: Vec, - storages: Vec, - transactions: Vec, - transaction_receipts: Vec, - tasks: Vec, - ) -> Self { - Self { - results_root, - tasks_root, - headers, - mmr, - accounts, - storages, - transactions, - transaction_receipts, - tasks, - } - } - - pub fn update_results_root(&mut self, results_root: String) { - self.results_root = Some(results_root); - } -} diff --git a/crates/primitives/src/task/datalake/mod.rs b/crates/primitives/src/task/datalake/mod.rs index 27bb3a22..0e7a399c 100644 --- a/crates/primitives/src/task/datalake/mod.rs +++ b/crates/primitives/src/task/datalake/mod.rs @@ -10,7 +10,7 @@ pub mod datalake_type; pub mod envelope; pub mod transactions; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct DatalakeCompute { pub datalake: DatalakeEnvelope, pub compute: Computation, diff --git a/crates/primitives/src/task/mod.rs b/crates/primitives/src/task/mod.rs index 5c4dc8d6..f9e4ff05 100644 --- a/crates/primitives/src/task/mod.rs +++ b/crates/primitives/src/task/mod.rs @@ -1,6 +1,7 @@ //! Task is a unit of work that can be executed by the processor/pre-processor. use crate::solidity_types::traits::DatalakeComputeCodecs; use alloy::primitives::B256; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use datalake::DatalakeCompute; use module::Module; @@ -9,16 +10,54 @@ pub mod module; /// [`TaskEnvelope`] is a structure that contains task itself /// This structure is used to provide the task to the pre-processor +#[derive(Clone, Debug)] pub enum TaskEnvelope { DatalakeCompute(DatalakeCompute), - Module(Module), + Module(ExtendedModule), +} + +#[derive(Clone, Debug)] +pub struct ExtendedModule { + pub task: Module, + pub module_class: CasmContractClass, } impl TaskEnvelope { pub fn commit(&self) -> B256 { match self { TaskEnvelope::DatalakeCompute(task) => task.commit(), - TaskEnvelope::Module(module) => module.commit(), + TaskEnvelope::Module(module) => module.task.commit(), } } + + pub fn divide_tasks(tasks: Vec) -> (Vec, Vec) { + // Partition the tasks into datalake and module tasks + let (datalake_envelopes, module_envelopes): (Vec<_>, Vec<_>) = tasks + .into_iter() + .partition(|task| matches!(task, TaskEnvelope::DatalakeCompute(_))); + + let datalake_tasks = datalake_envelopes + .into_iter() + .filter_map(|task| { + if let TaskEnvelope::DatalakeCompute(datalake_task) = task { + Some(datalake_task) + } else { + None + } + }) + .collect(); + + let module_tasks = module_envelopes + .into_iter() + .filter_map(|task| { + if let TaskEnvelope::Module(module_task) = task { + Some(module_task) + } else { + None + } + }) + .collect(); + + (datalake_tasks, module_tasks) + } } diff --git a/crates/primitives/src/task/module.rs b/crates/primitives/src/task/module.rs index 9e73612f..f6596807 100644 --- a/crates/primitives/src/task/module.rs +++ b/crates/primitives/src/task/module.rs @@ -2,10 +2,12 @@ //! It contains the hash and the input. //! This is request interface for the preprocessor. +use std::path::PathBuf; + use alloy::primitives::{keccak256, Keccak256, B256}; use serde::Serialize; use serde_with::serde_as; -use starknet::core::serde::unsigned_field_element::UfeHex; +use starknet::core::{serde::unsigned_field_element::UfeHex, types::FromStrError}; use starknet_crypto::FieldElement; #[serde_as] @@ -15,6 +17,7 @@ pub struct Module { pub class_hash: FieldElement, #[serde_as(as = "Vec")] pub inputs: Vec, + pub local_class_path: Option, } pub enum ModuleTag { @@ -25,15 +28,44 @@ impl Module { pub fn from_tag(tag: ModuleTag, inputs: Vec) -> Self { let class_hash = match tag { ModuleTag::AccountBalanceExample => FieldElement::from_hex_be( - "0x07d6c339c3e2236d2821c1c89d4a0e9027cd6c7e491189e9694a6df7c8f10aae", + "0x034d4ff54bc5c6cfee6719bfaa94ffa374071e8d656b74823681a955e9033dd9", ), } .expect("Invalid module tag"); - Self { class_hash, inputs } + Self { + class_hash, + inputs, + local_class_path: None, + } + } + + pub fn new_from_string( + class_hash: String, + inputs: Vec, + local_class_path: Option, + ) -> Result { + let class_hash = FieldElement::from_hex_be(&class_hash)?; + let inputs = inputs + .iter() + .map(|x| FieldElement::from_hex_be(x)) + .collect::, _>>()?; + Ok(Self { + class_hash, + inputs, + local_class_path, + }) } - pub fn new(class_hash: FieldElement, inputs: Vec) -> Self { - Self { class_hash, inputs } + pub fn new( + class_hash: FieldElement, + inputs: Vec, + local_class_path: Option, + ) -> Self { + Self { + class_hash, + inputs, + local_class_path, + } } pub fn get_class_hash(&self) -> FieldElement { @@ -52,7 +84,6 @@ impl Module { let mut hasher = Keccak256::new(); hasher.update(self.class_hash.to_bytes_be()); hasher.update(commit_input); - hasher.clone().finalize() } } diff --git a/crates/processor/Cargo.toml b/crates/processor/Cargo.toml index ecfaccd1..0f9feb41 100644 --- a/crates/processor/Cargo.toml +++ b/crates/processor/Cargo.toml @@ -18,3 +18,4 @@ hdp-primitives = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } hdp-cairo-runner = { workspace = true } +tracing = { workspace = true } diff --git a/crates/processor/src/lib.rs b/crates/processor/src/lib.rs index f37b75fd..8ba707ee 100644 --- a/crates/processor/src/lib.rs +++ b/crates/processor/src/lib.rs @@ -7,14 +7,12 @@ use alloy::primitives::{FixedBytes, Keccak256, B256, U256}; use alloy_merkle_tree::standard_binary_tree::StandardMerkleTree; use anyhow::Result; use hdp_cairo_runner::cairo_run; -use hdp_primitives::processed_types::{ - cairo_format::AsCairoFormat, datalake_compute::ProcessedDatalakeCompute, - v1_query::ProcessedResult, -}; +use hdp_primitives::processed_types::cairo_format::AsCairoFormat; +use hdp_primitives::processed_types::mmr::MMRMeta; +use hdp_primitives::processed_types::query::ProcessorInput; use serde::Serialize; use std::path::PathBuf; - -use hdp_cairo_runner::run::RunResult; +use tracing::{debug, info}; pub struct Processor { program_path: PathBuf, @@ -22,45 +20,45 @@ pub struct Processor { #[derive(Debug, Serialize)] pub struct ProcessorResult { + /// raw results of the module + pub raw_results: Vec, /// leaf of result merkle tree - pub task_results: Vec, + pub results_commitments: Vec, /// leaf of task merkle tree - pub task_commitments: Vec, + pub tasks_commitments: Vec, /// tasks inclusion proofs pub task_inclusion_proofs: Vec>>, /// results inclusion proofs pub results_inclusion_proofs: Vec>>, /// root of the results merkle tree - pub results_root: String, + pub results_root: B256, /// root of the tasks merkle tree - pub tasks_root: String, - /// mmr id - pub used_mmr_id: u64, - /// mmr size - pub used_mmr_size: u64, + pub tasks_root: B256, + /// mmr metas related to processed tasks + pub mmr_metas: Vec, } impl ProcessorResult { #[allow(clippy::too_many_arguments)] pub fn new( - task_results: Vec, - task_commitments: Vec, + raw_results: Vec, + results_commitments: Vec, + tasks_commitments: Vec, task_inclusion_proofs: Vec>>, results_inclusion_proofs: Vec>>, - results_root: String, - tasks_root: String, - used_mmr_id: u64, - used_mmr_size: u64, + results_root: B256, + tasks_root: B256, + mmr_metas: Vec, ) -> Self { Self { - task_results, - task_commitments, + raw_results, + results_commitments, + tasks_commitments, task_inclusion_proofs, results_inclusion_proofs, results_root, tasks_root, - used_mmr_id, - used_mmr_size, + mmr_metas, } } } @@ -72,108 +70,65 @@ impl Processor { pub async fn process( &self, - requset: ProcessedResult, - pie_path: PathBuf, - ) -> Result { - // generate input file from fetch points - // 1. fetch proofs from provider by using fetch points - // TODO: only for module - // let proofs = self - // .provider - // .fetch_proofs_from_keys(requset.fetch_keys) - // .await?; - - // 2. generate input struct with proofs and module bytes - // let input = self.generate_input(requset).await?; - // 3. pass the input file to the runner + requset: ProcessorInput, + pie_path: &PathBuf, + ) -> Result { + // 1. pass the input file to the runner let input_string = serde_json::to_string_pretty(&requset.as_cairo_format()) .expect("Failed to serialize module class"); - let result = cairo_run(self.program_path.clone(), input_string, pie_path)?; - - let pr = self.build_legacy_output_file(requset, result)?; - - // let task_commitments: Vec = requset - // .tasks - // .iter() - // .map(|task| task.task_commitment.clone()) - // .collect(); - // let task_inclusion_proofs: Vec<_> = requset - // .tasks - // .iter() - // .map(|task| task.task_proof.clone()) - // .collect(); - - // let task_root = requset.tasks_root.clone(); - - // let (results_tree, result_commitments) = - // self.build_result_merkle_tree(task_commitments.clone(), result.task_results.clone())?; - // let results_inclusion_proofs: Vec<_> = result_commitments - // .iter() - // .map(|rc| results_tree.get_proof(&DynSolValue::FixedBytes(*rc, 32))) - // .collect(); - // let result_root = results_tree.root().to_string(); - // let mmr = requset.mmr.clone(); - - Ok(pr) - } - - // TODO: for now, we are using the legacy output file format. - fn build_legacy_output_file( - &self, - requset: ProcessedResult, - result: RunResult, - ) -> Result { - let task_commitments: Vec = requset + let result = cairo_run(&self.program_path, input_string, pie_path)?; + let cairo_run_output = result.cairo_run_output; + let tasks_commitments: Vec = requset .tasks .iter() - .map(|task| task.task_commitment) + .map(|task| task.get_task_commitment()) .collect(); - // let task_inclusion_proofs: Vec<_> = requset - // .tasks - // .iter() - // .map(|task| task.task_proof.clone()) - // .collect(); + let task_inclusion_proofs: Vec> = requset + .tasks + .iter() + .map(|task| task.get_task_proof()) + .collect(); + let task_root = requset.tasks_root; - let task_root = requset.tasks_root.clone(); - let (results_tree, result_commitments) = - self.build_result_merkle_tree(task_commitments.clone(), result.task_results.clone())?; + let (results_tree, result_commitments) = self.build_result_merkle_tree( + tasks_commitments.clone(), + cairo_run_output.results.clone(), + )?; let results_inclusion_proofs: Vec<_> = result_commitments .iter() .map(|rc| results_tree.get_proof(&DynSolValue::FixedBytes(*rc, 32))) .collect(); - let result_root = results_tree.root().to_string(); - - let mut new_tasks: Vec = Vec::new(); - for (idx, mut task) in requset.tasks.into_iter().enumerate() { - let compiled_result = result.task_results[idx]; - let result_commitment = result_commitments[idx]; - let result_proof = results_inclusion_proofs[idx].clone(); - task.update_results(compiled_result, result_commitment, result_proof); - new_tasks.push(task.clone()); - } - - let new_final_processed_result = ProcessedResult { - results_root: Some(result_root), - tasks_root: task_root, - headers: requset.headers, - mmr: requset.mmr, - accounts: requset.accounts, - storages: requset.storages, - transactions: requset.transactions, - transaction_receipts: requset.transaction_receipts, - tasks: new_tasks, - }; - Ok(new_final_processed_result) + let result_root = results_tree.root(); + let processor_result = ProcessorResult::new( + cairo_run_output + .results + .iter() + .map(|x| B256::from(*x)) + .collect(), + result_commitments, + tasks_commitments, + task_inclusion_proofs, + results_inclusion_proofs, + result_root, + task_root, + requset.proofs.mmr_metas, + ); + info!("2️⃣ Processor completed successfully"); + Ok(processor_result) } fn build_result_merkle_tree( &self, - task_commitments: Vec, + tasks_commitments: Vec, task_results: Vec, ) -> Result<(StandardMerkleTree, Vec>)> { let mut results_leaves = Vec::new(); let mut results_commitments = Vec::new(); - for (task_commitment, task_result) in task_commitments.iter().zip(task_results.iter()) { + for (task_commitment, task_result) in tasks_commitments.iter().zip(task_results.iter()) { + debug!( + "building result merkle tree | task_commitment: {:?}, task_result: {:?}", + task_commitment, task_result + ); let result_commitment = self._raw_result_to_result_commitment(task_commitment, task_result); results_commitments.push(result_commitment); diff --git a/crates/provider/benches/provider_benchmark.rs b/crates/provider/benches/provider_benchmark.rs index 1e53a4ad..7238eae2 100644 --- a/crates/provider/benches/provider_benchmark.rs +++ b/crates/provider/benches/provider_benchmark.rs @@ -1,15 +1,11 @@ use alloy::primitives::{address, B256}; use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use hdp_provider::evm::provider::EvmProvider; // Adjust this import path according to your project structure -use reqwest::Url; -use tokio::runtime::Runtime; -// Note: this is non-paid alchemy rpc url -const SEPOLIA_RPC_URL: &str = - "https://eth-sepolia.g.alchemy.com/v2/xar76cftwEtqTBWdF4ZFy9n8FLHAETDv"; +use tokio::runtime::Runtime; fn benchmark_header(b: &mut Bencher) { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let rt = Runtime::new().unwrap(); b.iter(|| { @@ -23,7 +19,7 @@ fn benchmark_header(b: &mut Bencher) { } fn benchmark_account(b: &mut Bencher) { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let target_address = address!("7f2c6f930306d3aa736b3a6c6a98f512f74036d4"); let rt = Runtime::new().unwrap(); @@ -38,7 +34,7 @@ fn benchmark_account(b: &mut Bencher) { } fn benchmark_storage(b: &mut Bencher) { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let target_address = address!("75CeC1db9dCeb703200EAa6595f66885C962B920"); let storage_key = B256::ZERO; let rt = Runtime::new().unwrap(); @@ -54,7 +50,7 @@ fn benchmark_storage(b: &mut Bencher) { } fn benchmark_transaction(b: &mut Bencher) { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let rt = Runtime::new().unwrap(); b.iter(|| { @@ -68,7 +64,7 @@ fn benchmark_transaction(b: &mut Bencher) { } fn benchmark_transaction_receipt(b: &mut Bencher) { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let rt = Runtime::new().unwrap(); b.iter(|| { diff --git a/crates/provider/src/evm/config.rs b/crates/provider/src/evm/config.rs new file mode 100644 index 00000000..8c8b85dd --- /dev/null +++ b/crates/provider/src/evm/config.rs @@ -0,0 +1,32 @@ +use reqwest::Url; + +/// This is optimal max number of requests to send in parallel when using non-paid alchemy rpc url +pub const DEFAULT_MAX_REQUESTS: u64 = 100; +const DEFAULT_CHAIN_ID: u64 = 11155111; +const DEFAULT_RPC_URL: &str = + "https://eth-sepolia.g.alchemy.com/v2/xar76cftwEtqTBWdF4ZFy9n8FLHAETDv"; + +/// EVM provider configuration +#[derive(Clone, Debug)] +pub struct EvmProviderConfig { + /// RPC url + pub rpc_url: Url, + /// Chain id + pub chain_id: u64, + /// Max number of requests to send in parallel + /// + /// For default, it is set to 100 + /// For archive node, recommend to set it to 1000 + /// This will effect fetch speed of account, storage proofs + pub max_requests: u64, +} + +impl Default for EvmProviderConfig { + fn default() -> Self { + Self { + rpc_url: DEFAULT_RPC_URL.parse().unwrap(), + chain_id: DEFAULT_CHAIN_ID, + max_requests: DEFAULT_MAX_REQUESTS, + } + } +} diff --git a/crates/provider/src/evm/from_keys.rs b/crates/provider/src/evm/from_keys.rs index 61a6cd65..6d2ca546 100644 --- a/crates/provider/src/evm/from_keys.rs +++ b/crates/provider/src/evm/from_keys.rs @@ -4,7 +4,7 @@ use crate::key::{ AccountMemorizerKey, FetchKeyEnvelope, HeaderMemorizerKey, StorageMemorizerKey, TxMemorizerKey, TxReceiptMemorizerKey, }; -use alloy::primitives::{Address, BlockNumber, Bytes, TxIndex, B256}; +use alloy::primitives::{Address, BlockNumber, Bytes, ChainId, TxIndex, B256}; use alloy::transports::{RpcError, TransportErrorKind}; use eth_trie_proofs::tx_receipt_trie::TxReceiptsMptHandler; use eth_trie_proofs::tx_trie::TxsMptHandler; @@ -21,66 +21,125 @@ use std::collections::{HashMap, HashSet}; use std::time::Instant; use tracing::info; -impl EvmProvider { - /// This is the public entry point of provider. - pub async fn fetch_proofs_from_keys( - &self, - fetch_keys: Vec, - ) -> Result { - let mut target_keys_for_header = HashSet::new(); - let mut target_keys_for_account = HashSet::new(); - let mut target_keys_for_storage = HashSet::new(); - let mut target_keys_for_tx = HashSet::new(); - let mut target_keys_for_tx_receipt = HashSet::new(); - for key in fetch_keys { - match key { - FetchKeyEnvelope::Header(header_key) => { - target_keys_for_header.insert(header_key); - } - FetchKeyEnvelope::Account(account_key) => { - target_keys_for_header.insert(HeaderMemorizerKey::new( +#[derive(Debug, Default)] +/// This is keys that are categorized into different subsets of keys. +pub struct CategorizedFetchKeys { + pub headers: HashSet, + pub accounts: HashSet, + pub storage: HashSet, + pub txs: HashSet, + pub tx_receipts: HashSet, +} + +impl CategorizedFetchKeys { + pub fn new( + headers: HashSet, + accounts: HashSet, + storage: HashSet, + txs: HashSet, + tx_receipts: HashSet, + ) -> Self { + Self { + headers, + accounts, + storage, + txs, + tx_receipts, + } + } +} + +/// Categorize fetch keys +/// This is require to initiate multiple provider for different chain and fetch keys types +pub fn categorize_fetch_keys( + fetch_keys: Vec, +) -> Vec<(ChainId, CategorizedFetchKeys)> { + let mut chain_id_map: HashMap = std::collections::HashMap::new(); + + for key in fetch_keys { + let chain_id = key.get_chain_id(); + let target_categorized_fetch_keys = chain_id_map.entry(chain_id).or_default(); + + match key { + FetchKeyEnvelope::Header(header_key) => { + target_categorized_fetch_keys.headers.insert(header_key); + } + FetchKeyEnvelope::Account(account_key) => { + target_categorized_fetch_keys + .headers + .insert(HeaderMemorizerKey::new( account_key.chain_id, account_key.block_number, )); - target_keys_for_account.insert(account_key); - } - FetchKeyEnvelope::Storage(storage_key) => { - target_keys_for_header.insert(HeaderMemorizerKey::new( + target_categorized_fetch_keys.accounts.insert(account_key); + } + FetchKeyEnvelope::Storage(storage_key) => { + target_categorized_fetch_keys + .headers + .insert(HeaderMemorizerKey::new( storage_key.chain_id, storage_key.block_number, )); - target_keys_for_storage.insert(storage_key); - } - FetchKeyEnvelope::Tx(tx_key) => { - target_keys_for_header.insert(HeaderMemorizerKey::new( + target_categorized_fetch_keys.storage.insert(storage_key); + } + FetchKeyEnvelope::Tx(tx_key) => { + target_categorized_fetch_keys + .headers + .insert(HeaderMemorizerKey::new( tx_key.chain_id, tx_key.block_number, )); - target_keys_for_tx.insert(tx_key); - } - FetchKeyEnvelope::TxReceipt(tx_receipt_key) => { - target_keys_for_header.insert(HeaderMemorizerKey::new( + target_categorized_fetch_keys.txs.insert(tx_key); + } + FetchKeyEnvelope::TxReceipt(tx_receipt_key) => { + target_categorized_fetch_keys + .headers + .insert(HeaderMemorizerKey::new( tx_receipt_key.chain_id, tx_receipt_key.block_number, )); - target_keys_for_tx_receipt.insert(tx_receipt_key); - } + target_categorized_fetch_keys + .tx_receipts + .insert(tx_receipt_key); } } + } + chain_id_map.into_iter().collect() +} +impl EvmProvider { + /// This is the public entry point of provider. + pub async fn fetch_proofs_from_keys( + &self, + fetch_keys: CategorizedFetchKeys, + ) -> Result { // fetch proofs using keys and construct result - let (headers, mmr_meta) = self.get_headers_from_keys(target_keys_for_header).await?; - let mut accounts = self.get_accounts_from_keys(target_keys_for_account).await?; - let (accounts_from_storage_key, storages) = - self.get_storages_from_keys(target_keys_for_storage).await?; - let transactions = self.get_txs_from_keys(target_keys_for_tx).await?; - let transaction_receipts = self - .get_tx_receipts_from_keys(target_keys_for_tx_receipt) - .await?; + let (headers, mmr_metas) = self.get_headers_from_keys(fetch_keys.headers).await?; + let mut accounts = if fetch_keys.accounts.is_empty() { + HashSet::new() + } else { + self.get_accounts_from_keys(fetch_keys.accounts).await? + }; + let (accounts_from_storage_key, storages) = if fetch_keys.storage.is_empty() { + (HashSet::new(), HashSet::new()) + } else { + self.get_storages_from_keys(fetch_keys.storage).await? + }; + let transactions = if fetch_keys.txs.is_empty() { + vec![] + } else { + self.get_txs_from_keys(fetch_keys.txs).await? + }; + let transaction_receipts = if fetch_keys.tx_receipts.is_empty() { + vec![] + } else { + self.get_tx_receipts_from_keys(fetch_keys.tx_receipts) + .await? + }; accounts.extend(accounts_from_storage_key); let accounts_result: Vec = accounts.into_iter().collect(); Ok(ProcessedBlockProofs { - mmr_meta, + mmr_metas, headers: headers.into_iter().collect(), accounts: accounts_result, storages: storages.into_iter().collect(), @@ -92,7 +151,7 @@ impl EvmProvider { async fn get_headers_from_keys( &self, keys: HashSet, - ) -> Result<(HashSet, MMRMeta), ProviderError> { + ) -> Result<(HashSet, Vec), ProviderError> { let start_fetch = Instant::now(); let block_range = keys.iter().map(|x| x.block_number).collect::>(); @@ -107,8 +166,9 @@ impl EvmProvider { self._chunk_vec_blocks_for_indexer(block_range) }; + let chain_id = keys.iter().next().unwrap().chain_id; let mut fetched_headers_proofs: HashSet = HashSet::new(); - let mut mmr = None; + let mut mmrs = HashSet::new(); let real_target_blocks = keys.iter().map(|x| x.block_number).collect::>(); for target_blocks in target_blocks_batch { @@ -120,17 +180,6 @@ impl EvmProvider { .get_headers_proof(start_block, end_block) .await?; - // validate MMR among range of blocks - match mmr { - None => { - mmr = Some(indexer_response.mmr_meta); - } - Some(ref existing_mmr) if existing_mmr != &indexer_response.mmr_meta => { - return Err(ProviderError::MismatchedMMRMeta); - } - _ => {} - } - // filter only the keys that are in the real target blocks let keys_in_real_target_blocks = indexer_response .headers @@ -145,13 +194,17 @@ impl EvmProvider { }); fetched_headers_proofs.extend(keys_in_real_target_blocks); + let fetched_mmr = indexer_response.mmr_meta; + let mmr_meta = MMRMeta::from_indexer(fetched_mmr, chain_id); + mmrs.insert(mmr_meta); } let duration = start_fetch.elapsed(); info!("Time taken (Headers Proofs Fetch): {:?}", duration); - if let Some(fetched_mmr) = mmr { - Ok((fetched_headers_proofs, fetched_mmr.into())) + if !mmrs.is_empty() { + let vec_mmrs = mmrs.into_iter().collect::>(); + Ok((fetched_headers_proofs, vec_mmrs)) } else { Err(ProviderError::MmrNotFound) } @@ -383,30 +436,26 @@ mod tests { use crate::evm::provider::EvmProvider; use crate::key::{AccountMemorizerKey, HeaderMemorizerKey}; use alloy::primitives::address; - use reqwest::Url; - - const SEPOLIA_RPC_URL: &str = - "https://eth-sepolia.g.alchemy.com/v2/xar76cftwEtqTBWdF4ZFy9n8FLHAETDv"; #[tokio::test] async fn test_get_proofs_from_header_keys() { let target_chain_id = 11155111; - let provider = - EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), target_chain_id); + let provider = EvmProvider::default(); let keys = vec![ FetchKeyEnvelope::Header(HeaderMemorizerKey::new(target_chain_id, 1)), FetchKeyEnvelope::Header(HeaderMemorizerKey::new(target_chain_id, 2)), FetchKeyEnvelope::Header(HeaderMemorizerKey::new(target_chain_id, 3)), ]; - let proofs = provider.fetch_proofs_from_keys(keys).await.unwrap(); + let (chain_id, fetched_keys) = categorize_fetch_keys(keys).into_iter().next().unwrap(); + assert_eq!(chain_id, target_chain_id); + let proofs = provider.fetch_proofs_from_keys(fetched_keys).await.unwrap(); assert_eq!(proofs.headers.len(), 3); } #[tokio::test] async fn test_get_proofs_from_accounts_keys() { let target_chain_id = 11155111; - let provider = - EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), target_chain_id); + let provider = EvmProvider::default(); let target_address = address!("7f2c6f930306d3aa736b3a6c6a98f512f74036d4"); let keys = vec![ FetchKeyEnvelope::Account(AccountMemorizerKey::new( @@ -421,7 +470,9 @@ mod tests { target_address, )), ]; - let proofs = provider.fetch_proofs_from_keys(keys).await.unwrap(); + let (chain_id, fetched_keys) = categorize_fetch_keys(keys).into_iter().next().unwrap(); + assert_eq!(chain_id, target_chain_id); + let proofs = provider.fetch_proofs_from_keys(fetched_keys).await.unwrap(); assert_eq!(proofs.accounts[0].proofs.len(), 3); assert_eq!(proofs.headers.len(), 3); } @@ -430,8 +481,7 @@ mod tests { async fn test_proofs_from_storage_keys() { let start_fetch = Instant::now(); let target_chain_id = 11155111; - let provider = - EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), target_chain_id); + let provider = EvmProvider::default(); let target_address = address!("7f2c6f930306d3aa736b3a6c6a98f512f74036d4"); let target_slot = B256::ZERO; let keys = vec![ @@ -472,7 +522,9 @@ mod tests { target_slot, )), ]; - let proofs = provider.fetch_proofs_from_keys(keys).await.unwrap(); + let (chain_id, fetched_keys) = categorize_fetch_keys(keys).into_iter().next().unwrap(); + assert_eq!(chain_id, target_chain_id); + let proofs = provider.fetch_proofs_from_keys(fetched_keys).await.unwrap(); let duration = start_fetch.elapsed(); println!("Time taken (Total Proofs Fetch): {:?}", duration); assert_eq!(proofs.headers.len(), 6); @@ -483,14 +535,15 @@ mod tests { #[tokio::test] async fn test_get_proofs_from_tx_keys() { let target_chain_id = 11155111; - let provider = - EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), target_chain_id); + let provider = EvmProvider::default(); let keys = vec![ FetchKeyEnvelope::Tx(TxMemorizerKey::new(target_chain_id, 1000, 0)), FetchKeyEnvelope::Tx(TxMemorizerKey::new(target_chain_id, 1001, 1)), FetchKeyEnvelope::Tx(TxMemorizerKey::new(target_chain_id, 1000, 2)), ]; - let proofs = provider.fetch_proofs_from_keys(keys).await.unwrap(); + let (chain_id, fetched_keys) = categorize_fetch_keys(keys).into_iter().next().unwrap(); + assert_eq!(chain_id, target_chain_id); + let proofs = provider.fetch_proofs_from_keys(fetched_keys).await.unwrap(); assert_eq!(proofs.headers.len(), 2); assert_eq!(proofs.transactions.len(), 3); } diff --git a/crates/provider/src/evm/mod.rs b/crates/provider/src/evm/mod.rs index 552a8d31..0b45af91 100644 --- a/crates/provider/src/evm/mod.rs +++ b/crates/provider/src/evm/mod.rs @@ -1,3 +1,4 @@ +pub mod config; pub mod from_keys; pub mod provider; pub mod rpc; diff --git a/crates/provider/src/evm/provider.rs b/crates/provider/src/evm/provider.rs index 30c9d34e..69b1ac89 100644 --- a/crates/provider/src/evm/provider.rs +++ b/crates/provider/src/evm/provider.rs @@ -1,15 +1,18 @@ use alloy::{ - primitives::{Address, BlockNumber, Bytes, ChainId, StorageKey, TxIndex}, + primitives::{Address, BlockNumber, Bytes, StorageKey, TxIndex}, rpc::types::EIP1186AccountProofResponse, transports::{RpcError, TransportErrorKind}, }; use eth_trie_proofs::{ tx_receipt_trie::TxReceiptsMptHandler, tx_trie::TxsMptHandler, EthTrieError, }; -use hdp_primitives::block::header::{MMRMetaFromNewIndexer, MMRProofFromNewIndexer}; +use hdp_primitives::{block::header::MMRProofFromNewIndexer, processed_types::mmr::MMRMeta}; use itertools::Itertools; use reqwest::Url; -use std::{collections::HashMap, time::Instant}; +use std::{ + collections::{HashMap, HashSet}, + time::Instant, +}; use thiserror::Error; use tracing::info; @@ -18,10 +21,10 @@ use crate::{ types::{FetchedTransactionProof, FetchedTransactionReceiptProof}, }; -use super::rpc::{RpcProvider, RpcProviderError}; - -/// This is optimal max number of requests to send in parallel when using non-paid alchemy rpc url -const DEFAULT_MAX_REQUESTS: u64 = 100; +use super::{ + config::EvmProviderConfig, + rpc::{RpcProvider, RpcProviderError}, +}; /// Error from [`EvmProvider`] #[derive(Error, Debug)] @@ -71,19 +74,10 @@ pub struct EvmProvider { pub(crate) tx_provider_url: Url, } -/// EVM provider configuration -#[derive(Clone, Debug)] -pub struct EvmProviderConfig { - /// RPC url - pub rpc_url: Url, - /// Chain id - pub chain_id: u64, - /// Max number of requests to send in parallel - /// - /// For default, it is set to 100 - /// For archive node, recommend to set it to 1000 - /// This will effect fetch speed of account, storage proofs - pub max_requests: u64, +impl Default for EvmProvider { + fn default() -> Self { + Self::new(EvmProviderConfig::default()) + } } impl EvmProvider { @@ -98,17 +92,6 @@ impl EvmProvider { } } - pub fn new_with_url(url: Url, chain_id: ChainId) -> Self { - let rpc_provider = RpcProvider::new(url.clone(), DEFAULT_MAX_REQUESTS); - let header_provider = Indexer::new(chain_id); - - Self { - rpc_provider, - header_provider, - tx_provider_url: url, - } - } - /// Fetches the header proofs for the given block range. /// The header proofs are fetched from the indexer and the MMR meta is fetched from the indexer. /// @@ -122,7 +105,7 @@ impl EvmProvider { increment: u64, ) -> Result< ( - MMRMetaFromNewIndexer, + HashSet, HashMap, ), ProviderError, @@ -133,7 +116,7 @@ impl EvmProvider { self._chunk_block_range(from_block, to_block, increment); let mut fetched_headers_proofs_with_blocks_map = HashMap::new(); - let mut mmr = None; + let mut mmrs = HashSet::new(); for target_blocks in target_blocks_batch { let (start_block, end_block) = @@ -144,24 +127,16 @@ impl EvmProvider { .get_headers_proof(start_block, end_block) .await?; - // validate MMR among range of blocks - match mmr { - None => { - mmr = Some(indexer_response.mmr_meta); - } - Some(ref existing_mmr) if existing_mmr != &indexer_response.mmr_meta => { - return Err(ProviderError::MismatchedMMRMeta); - } - _ => {} - } fetched_headers_proofs_with_blocks_map.extend(indexer_response.headers); + let fetched_mmr = indexer_response.mmr_meta; + let mmr_meta = MMRMeta::from_indexer(fetched_mmr, self.header_provider.chain_id); + mmrs.insert(mmr_meta); } let duration = start_fetch.elapsed(); info!("Time taken (Headers Proofs Fetch): {:?}", duration); - - if let Some(fetched_mmr) = mmr { - Ok((fetched_mmr, fetched_headers_proofs_with_blocks_map)) + if !mmrs.is_empty() { + Ok((mmrs, fetched_headers_proofs_with_blocks_map)) } else { Err(ProviderError::MmrNotFound) } @@ -436,14 +411,11 @@ mod tests { use super::*; use alloy::primitives::{address, B256}; - const SEPOLIA_RPC_URL: &str = - "https://eth-sepolia.g.alchemy.com/v2/xar76cftwEtqTBWdF4ZFy9n8FLHAETDv"; - #[ignore = "too many requests, recommend to run locally"] #[tokio::test] async fn test_get_2000_range_of_account_proofs() -> Result<(), ProviderError> { let start_time = Instant::now(); - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 1155511); + let provider = EvmProvider::default(); let target_address = address!("7f2c6f930306d3aa736b3a6c6a98f512f74036d4"); let response = provider .get_range_of_account_proofs(6127485, 6127485 + 2000 - 1, 1, target_address) @@ -460,7 +432,7 @@ mod tests { #[tokio::test] async fn test_get_2000_range_of_storage_proofs() -> Result<(), ProviderError> { let start_time = Instant::now(); - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let target_address = address!("75CeC1db9dCeb703200EAa6595f66885C962B920"); let result = provider .get_range_of_storage_proofs(6127485, 6127485 + 2000 - 1, 1, target_address, B256::ZERO) @@ -477,7 +449,7 @@ mod tests { #[tokio::test] async fn test_get_2000_range_of_header_proofs() -> Result<(), ProviderError> { let start_time = Instant::now(); - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let (_meta, header_response) = provider .get_range_of_header_proofs(6127485, 6127485 + 2000 - 1, 1) .await?; @@ -490,7 +462,7 @@ mod tests { #[tokio::test] async fn test_get_parallel_4_all_tx_with_proof_from_block() { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let task1 = { let provider = provider.clone(); @@ -542,7 +514,7 @@ mod tests { #[tokio::test] async fn test_get_parallel_4_all_tx_receipt_with_proof_from_block() { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let task1 = { let provider = provider.clone(); tokio::spawn(async move { @@ -594,7 +566,7 @@ mod tests { #[tokio::test] async fn test_error_get_tx_with_proof_from_block() { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 11155111); + let provider = EvmProvider::default(); let response = provider .get_tx_with_proof_from_block(6127485, 0, 2000, 1) .await; @@ -607,7 +579,7 @@ mod tests { #[tokio::test] async fn test_error_get_tx_receipt_with_proof_from_block() { - let provider = EvmProvider::new_with_url(Url::parse(SEPOLIA_RPC_URL).unwrap(), 1155511); + let provider = EvmProvider::default(); let response = provider .get_tx_receipt_with_proof_from_block(6127485, 0, 2000, 1) .await; diff --git a/crates/provider/src/indexer.rs b/crates/provider/src/indexer.rs index 94bf0000..70ed91a7 100644 --- a/crates/provider/src/indexer.rs +++ b/crates/provider/src/indexer.rs @@ -53,7 +53,7 @@ pub enum IndexerError { #[derive(Clone)] pub struct Indexer { client: Client, - chain_id: u64, + pub chain_id: u64, } #[derive(Debug)] diff --git a/demo.dockerfile b/demo.dockerfile new file mode 100644 index 00000000..35b55311 --- /dev/null +++ b/demo.dockerfile @@ -0,0 +1,30 @@ +FROM dataprocessor/hdp-cairo:v0.0.8 + +# Set shell to bash and define working directory +SHELL ["/bin/bash", "-ci"] +WORKDIR /hdp-demo + +# Install Rust using Rustup +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \ + echo 'export PATH="/root/.cargo/bin:$PATH"' >> /root/.bashrc + +# Add Cargo executables to PATH +RUN mkdir -p /root/.local/bin && \ + echo 'export PATH="/root/.local/bin:$PATH"' >> /root/.bashrc + +# Create necessary directories +RUN mkdir -p /hdp-demo/build/compiled_cairo + +# Copy specific file from the base image +RUN cp /hdp-cairo/build/hdp.json /hdp-demo/build/compiled_cairo/hdp.json +RUN cp /hdp-cairo/build/contract_dry_run.json /hdp-demo/build/compiled_cairo/contract_dry_run.json + +# Copy the rest of the application source +COPY . . + +# Install Rust dependencies and build the Rust application +RUN cargo install --path cli + +# Run the final command ensuring the environment is correctly sourced +CMD source /root/.bashrc && \ + hdp run-module 0x4F21E5,0x4F21E8,0x13cb6ae34a13a0977f4d7101ebc24b87bb23f0d5 -p /hdp-demo/hdp_input.json -o /hdp-demo/output.json -c /hdp-demo/cairo.pie --chain-id 11155111 --class-hash 0x00ababb33ae5911fd14e6b9f2853b6271f553b9ec7835298134f4bb020100971 --rpc-url https://sepolia.ethereum.iosis.tech/ --module-registry-rpc-url https://pathfinder.sepolia.iosis.tech/ \ No newline at end of file diff --git a/dry_run_input.json b/dry_run_input.json new file mode 100644 index 00000000..99c28322 --- /dev/null +++ b/dry_run_input.json @@ -0,0 +1,1959 @@ +{ + "dry_run_output_path": "dry_run_output.json", + "modules": [ + { + "inputs": [ + "0x4f21e5", + "0x4f21e8", + "0x13cb6ae34a13a0977f4d7101ebc24b87bb23f0d5" + ], + "module_class": { + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "compiler_version": "2.6.4", + "bytecode": [ + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0xfffffffffffffffffffffffffffff6f0", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x11d", + "0x4825800180007ffa", + "0x910", + "0x400280007ff97fff", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0x125", + "0x482680017ff98000", + "0x1", + "0x20680017fff7ffa", + "0x104", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff47fff8000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xde", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffe", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480080007ff57fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480080017ff37fff", + "0x400080027ff27ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0xc9", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x482480017ffe8000", + "0xffffffffffffffffffffffff00000000", + "0x400080017ff77fff", + "0x482480017ff78000", + "0x2", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff47fff8000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x9b", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x12", + "0x4824800180007ffe", + "0x100000000", + "0x4844800180008002", + "0x8000000000000110000000000000000", + "0x4830800080017ffe", + "0x480080007ff57fff", + "0x482480017ffe8000", + "0xefffffffffffffde00000000ffffffff", + "0x480080017ff37fff", + "0x400080027ff27ffb", + "0x402480017fff7ffb", + "0xffffffffffffffffffffffffffffffff", + "0x20680017fff7fff", + "0x86", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x482480017ffe8000", + "0xffffffffffffffffffffffff00000000", + "0x400080017ff77fff", + "0x482480017ff78000", + "0x2", + "0x48307ff880007ff9", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff48000", + "0x10780017fff7fff", + "0x8", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x5b", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ff77fff8000", + "0x48127fba7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x305", + "0x482480017fff8000", + "0x304", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fb8", + "0xa0a", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff27fff", + "0x10780017fff7fff", + "0x2b", + "0x4824800180007fb8", + "0xa0a", + "0x400080007ff37fff", + "0x482480017ff38000", + "0x1", + "0x48127ffe7fff8000", + "0x480a7ffb7fff8000", + "0x48127fe47fff8000", + "0x48127fec7fff8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x48127fd87fff8000", + "0x48127fd87fff8000", + "0x48127fef7fff8000", + "0x1104800180018000", + "0x132", + "0x20680017fff7ffc", + "0xf", + "0x40780017fff7fff", + "0x1", + "0x400080007fff7ffc", + "0x400080017fff7ffd", + "0x48127ff87fff8000", + "0x48127ff87fff8000", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x482480017ffa8000", + "0x2", + "0x208b7fff7fff7ffe", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff08000", + "0x1", + "0x48127fb37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202334", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127fbb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482480017ff28000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x8", + "0x48127ff27fff8000", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fbb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x482480017ff28000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x8", + "0x48127ff27fff8000", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fc47fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fd27fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x480280007ffc8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x29", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", + "0x1", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xa", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff77fff8000", + "0x48127ffb7fff8000", + "0x10780017fff7fff", + "0x16", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0xc", + "0x40780017fff7fff", + "0x5", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffd", + "0x60", + "0x48307ffb80007ffc", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffa8000", + "0x1", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff78000", + "0x10780017fff7fff", + "0x8", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x29", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", + "0x1", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xa", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff77fff8000", + "0x48127ffb7fff8000", + "0x10780017fff7fff", + "0x16", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0xc", + "0x40780017fff7fff", + "0x5", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffd", + "0xb", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127fec7fff8000", + "0x48127fec7fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0xf", + "0x48127fec7fff8000", + "0x48127fec7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ff58000", + "0xffffffffffffffffffffffffffffa196", + "0x400280007ff47fff", + "0x10780017fff7fff", + "0xb2", + "0x4825800180007ff5", + "0x5e6a", + "0x400280007ff47fff", + "0x48297ff880017ff7", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280017ff47fff", + "0x10780017fff7fff", + "0xd", + "0x400280017ff47fff", + "0x482680017ff48000", + "0x2", + "0x48127ffc7fff8000", + "0x480a7ff67fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ff97fff8000", + "0x480a7ffa7fff8000", + "0x480a7ff77fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ff48000", + "0x2", + "0x48127ffb7fff8000", + "0x480a7ff67fff8000", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x480680017fff8000", + "0xaa36a7", + "0x480a7ff77fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0xa1", + "0x20680017fff7ffd", + "0x84", + "0x48327fff7ffa8001", + "0xa0680017fff7fff", + "0x7", + "0x4824800180007fff", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0xc", + "0x400080007ff87fff", + "0x40780017fff7fff", + "0x1", + "0x482480017ff78000", + "0x1", + "0x48127ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0x7", + "0x482480017ff78000", + "0x1", + "0x48127ffe7fff8000", + "0x480680017fff8000", + "0x1", + "0x48327ff87ff98001", + "0xa0680017fff7fff", + "0x7", + "0x4824800180007fff", + "0x100000000000000000000000000000000", + "0x400080007ffa7fff", + "0x10780017fff7fff", + "0xc", + "0x400080007ffb7fff", + "0x40780017fff7fff", + "0x5", + "0x482480017ff68000", + "0x1", + "0x48127ff97fff8000", + "0x48127ff57fff8000", + "0x48127ff57fff8000", + "0x10780017fff7fff", + "0x1c", + "0x480680017fff8000", + "0x1", + "0x48307fff7ffa8001", + "0xa0680017fff7fff", + "0x7", + "0x4824800180007fff", + "0x100000000000000000000000000000000", + "0x400080017ff67fff", + "0x10780017fff7fff", + "0xc", + "0x400080017ff77fff", + "0x40780017fff7fff", + "0x1", + "0x482480017ff68000", + "0x2", + "0x48127ffa7fff8000", + "0x48127ffc7fff8000", + "0x48127ff57fff8000", + "0x10780017fff7fff", + "0x8", + "0x482480017ff68000", + "0x2", + "0x48127ffa7fff8000", + "0x48127ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x20680017fff7fff", + "0x2f", + "0x480680017fff8000", + "0x1", + "0xa0680017fff8000", + "0x8", + "0x48327ffe7ff78000", + "0x4824800180007fff", + "0x100000000", + "0x400080007ff87fff", + "0x10780017fff7fff", + "0x14", + "0x48327ffe7ff78001", + "0x4824800180007fff", + "0xffffffffffffffffffffffff00000000", + "0x400080007ff87ffe", + "0x482480017ff88000", + "0x1", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x48127ffc7fff8000", + "0x480a7ff87fff8000", + "0x48127ff47fff8000", + "0x48127ff47fff8000", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffff78", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x7533325f616464204f766572666c6f77", + "0x400080007ffe7fff", + "0x482480017ff68000", + "0x1", + "0x48127fe37fff8000", + "0x48127fe37fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x753235365f616464204f766572666c6f77", + "0x400080007ffe7fff", + "0x48127ffa7fff8000", + "0x48127fe77fff8000", + "0x48127fe77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff48000", + "0x1", + "0x480a7ff57fff8000", + "0x480a7ff67fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x1", + "0xa0680017fff8004", + "0xe", + "0x4824800180047ffe", + "0x800000000000000000000000000000000000000000000000000000000000000", + "0x484480017ffe8000", + "0x110000000000000000", + "0x48307ffe7fff8002", + "0x480280007ff67ffc", + "0x480280017ff67ffc", + "0x402480017ffb7ffd", + "0xffffffffffffffeeffffffffffffffff", + "0x400280027ff67ffd", + "0x10780017fff7fff", + "0xce", + "0x484480017fff8001", + "0x8000000000000000000000000000000", + "0x48307fff80007ffd", + "0x480280007ff67ffd", + "0x480280017ff67ffd", + "0x402480017ffc7ffe", + "0xf8000000000000000000000000000000", + "0x400280027ff67ffe", + "0x40780017fff7fff", + "0x1", + "0x400180007fff7ff9", + "0x400180017fff7ffa", + "0x400180027fff7ffb", + "0x400180037fff7ffc", + "0x400180047fff7ffd", + "0x480680017fff8000", + "0x0", + "0x48127ffe7fff8000", + "0x482480017ffd8000", + "0x5", + "0x482680017ff68000", + "0x3", + "0x480680017fff8000", + "0x43616c6c436f6e7472616374", + "0x400280007ff87fff", + "0x400380017ff87ff7", + "0x400280027ff87ff4", + "0x400280037ff87ffb", + "0x400280047ff87ffc", + "0x400280057ff87ffd", + "0x480280077ff88000", + "0x20680017fff7fff", + "0xa2", + "0x480280087ff88000", + "0x480280097ff88000", + "0x480680017fff8000", + "0x0", + "0x480280067ff88000", + "0x482680017ff88000", + "0xa", + "0x480280087ff88000", + "0x480280097ff88000", + "0x48307ff980007ffa", + "0xa0680017fff8000", + "0x6", + "0x48307ffe80007ff9", + "0x400080007ff37fff", + "0x10780017fff7fff", + "0x81", + "0x482480017ff98000", + "0x1", + "0x48307fff80007ffd", + "0x400080007ff27fff", + "0x48307ff77ff58000", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x16", + "0x480080017fef8003", + "0x480080027fee8003", + "0x4844800180017ffe", + "0x100000000000000000000000000000000", + "0x483080017ffd7ffb", + "0x482480017fff7ffd", + "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", + "0x20680017fff7ffc", + "0x6", + "0x402480017fff7ffd", + "0xffffffffffffffffffffffffffffffff", + "0x10780017fff7fff", + "0x4", + "0x402480017ffe7ffd", + "0xf7ffffffffffffef0000000000000000", + "0x400080037fea7ffd", + "0x20680017fff7ffe", + "0x56", + "0x402780017fff7fff", + "0x1", + "0x400080017fef7ffe", + "0x480680017fff8000", + "0x1", + "0x48307ff680007ff7", + "0xa0680017fff8000", + "0x6", + "0x48307ffe80007ffd", + "0x400080027feb7fff", + "0x10780017fff7fff", + "0x39", + "0x482480017ffd8000", + "0x1", + "0x48307fff80007ffd", + "0x400080027fea7fff", + "0x48307ffb7ff28000", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x16", + "0x480080037fe78003", + "0x480080047fe68003", + "0x4844800180017ffe", + "0x100000000000000000000000000000000", + "0x483080017ffd7ffb", + "0x482480017fff7ffd", + "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", + "0x20680017fff7ffc", + "0x6", + "0x402480017fff7ffd", + "0xffffffffffffffffffffffffffffffff", + "0x10780017fff7fff", + "0x4", + "0x402480017ffe7ffd", + "0xf7ffffffffffffef0000000000000000", + "0x400080057fe27ffd", + "0x20680017fff7ffe", + "0x10", + "0x402780017fff7fff", + "0x1", + "0x400080037fe77ffe", + "0x40780017fff7fff", + "0x7", + "0x482480017fe08000", + "0x4", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x0", + "0x48127feb7fff8000", + "0x48127ff27fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x6", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x9", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e646578206f7574206f6620626f756e6473", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x3", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x8", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x4", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x11", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e646578206f7574206f6620626f756e6473", + "0x400080007ffe7fff", + "0x482480017fe08000", + "0x1", + "0x48127fe57fff8000", + "0x48127fe57fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1d", + "0x48127fe07fff8000", + "0x480280067ff88000", + "0x482680017ff88000", + "0xa", + "0x480680017fff8000", + "0x1", + "0x480280087ff88000", + "0x480280097ff88000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x21", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482680017ff68000", + "0x3", + "0x480a7ff77fff8000", + "0x480a7ff87fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe" + ], + "bytecode_segment_lengths": [ + 305, + 181, + 200, + 237 + ], + "hints": [ + [ + 0, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x910" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -6 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 40, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -1 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 44, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 86, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "AP", + "offset": -1 + }, + "b": { + "Immediate": "0x0" + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 90, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "scalar": { + "Immediate": "0x8000000000000110000000000000000" + }, + "max_x": { + "Immediate": "0xfffffffffffffffffffffffffffffffe" + }, + "x": { + "register": "AP", + "offset": 0 + }, + "y": { + "register": "AP", + "offset": 1 + } + } + } + ] + ], + [ + 136, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 155, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0xa0a" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -71 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 184, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 205, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 220, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 241, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 262, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 276, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 290, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 486, + [ + { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x5e6a" + }, + "rhs": { + "Deref": { + "register": "FP", + "offset": -11 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 497, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 530, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 553, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 573, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": 0 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 600, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { + "register": "FP", + "offset": -9 + }, + "b": { + "Deref": { + "register": "AP", + "offset": -1 + } + } + } + }, + "rhs": { + "Immediate": "0x100000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 626, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 643, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 669, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 688, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": 4 + } + } + } + ] + ], + [ + 692, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": 3 + } + }, + "scalar": { + "Immediate": "0x110000000000000000" + }, + "max_x": { + "Immediate": "0xffffffffffffffffffffffffffffffff" + }, + "x": { + "register": "AP", + "offset": -2 + }, + "y": { + "register": "AP", + "offset": -1 + } + } + } + ] + ], + [ + 702, + [ + { + "LinearSplit": { + "value": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "scalar": { + "Immediate": "0x8000000000000000000000000000000" + }, + "max_x": { + "Immediate": "0xffffffffffffffffffffffffffffffff" + }, + "x": { + "register": "AP", + "offset": -1 + }, + "y": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 710, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 732, + [ + { + "SystemCall": { + "system": { + "Deref": { + "register": "FP", + "offset": -8 + } + } + } + } + ] + ], + [ + 745, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -6 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 757, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 759, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 3 + }, + "remainder": { + "register": "AP", + "offset": 4 + } + } + } + ] + ], + [ + 783, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 795, + [ + { + "TestLessThan": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -1 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 797, + [ + { + "DivMod": { + "lhs": { + "Deref": { + "register": "AP", + "offset": -2 + } + }, + "rhs": { + "Immediate": "0x100000000000000000000000000000000" + }, + "quotient": { + "register": "AP", + "offset": 3 + }, + "remainder": { + "register": "AP", + "offset": 4 + } + } + } + ] + ], + [ + 829, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 846, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 863, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 880, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ], + [ + 908, + [ + { + "AllocSegment": { + "dst": { + "register": "AP", + "offset": 0 + } + } + } + ] + ] + ], + "pythonic_hints": [ + [ + 0, + [ + "memory[ap + 0] = 2320 <= memory[fp + -6]" + ] + ], + [ + 40, + [ + "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" + ] + ], + [ + 44, + [ + "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" + ] + ], + [ + 86, + [ + "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" + ] + ], + [ + 90, + [ + "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" + ] + ], + [ + 136, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 155, + [ + "memory[ap + 0] = 2570 <= memory[ap + -71]" + ] + ], + [ + 184, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 205, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 220, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 241, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 262, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 276, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 290, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 486, + [ + "memory[ap + 0] = 24170 <= memory[fp + -11]" + ] + ], + [ + 497, + [ + "memory[ap + -1] = memory[ap + 0] < 4294967296" + ] + ], + [ + 530, + [ + "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" + ] + ], + [ + 553, + [ + "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" + ] + ], + [ + 573, + [ + "memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456" + ] + ], + [ + 600, + [ + "memory[ap + 0] = (memory[fp + -9] + memory[ap + -1]) % PRIME < 4294967296" + ] + ], + [ + 626, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 643, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 669, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 688, + [ + "memory[ap + 4] = memory[ap + -1] < 3618502788666131106986593281521497120414687020801267626233049500247285301248" + ] + ], + [ + 692, + [ + "\n(value, scalar) = (memory[ap + 3], 313594649253062377472)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -2] = x\nmemory[ap + -1] = y\n" + ] + ], + [ + 702, + [ + "\n(value, scalar) = (memory[ap + -2], 10633823966279326983230456482242756608)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -1] = x\nmemory[ap + 0] = y\n" + ] + ], + [ + 710, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 732, + [ + "syscall_handler.syscall(syscall_ptr=memory[fp + -8])" + ] + ], + [ + 745, + [ + "memory[ap + 0] = memory[ap + -6] < memory[ap + -1]" + ] + ], + [ + 757, + [ + "memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456" + ] + ], + [ + 759, + [ + "(memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456)" + ] + ], + [ + 783, + [ + "memory[ap + 0] = memory[ap + -2] < memory[ap + -1]" + ] + ], + [ + 795, + [ + "memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456" + ] + ], + [ + 797, + [ + "(memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456)" + ] + ], + [ + 829, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 846, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 863, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 880, + [ + "memory[ap + 0] = segments.add()" + ] + ], + [ + 908, + [ + "memory[ap + 0] = segments.add()" + ] + ] + ], + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0xe2054f8a912367e38a22ce773328ff8aabf8082c4120bad9ef085e1dbf29a7", + "offset": 0, + "builtins": [ + "range_check" + ] + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + } + } + } + ] +} \ No newline at end of file diff --git a/dry_run_output.json b/dry_run_output.json new file mode 100644 index 00000000..bec4ffaa --- /dev/null +++ b/dry_run_output.json @@ -0,0 +1 @@ +[{"fetch_keys": [{"key": {"chain_id": 11155111, "block_number": 5186021, "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5"}, "type": "AccountMemorizerKey"}, {"key": {"chain_id": 11155111, "block_number": 5186022, "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5"}, "type": "AccountMemorizerKey"}, {"key": {"chain_id": 11155111, "block_number": 5186023, "address": "0x13CB6AE34A13a0977F4d7101eBc24B87Bb23F0d5"}, "type": "AccountMemorizerKey"}], "result": {"low": "0x0", "high": "0x0"}, "class_hash": "0x382f2154d4f7baf0e67388ee86f7069b5502dc7fbe2d47f73b569b22091c9ae"}] \ No newline at end of file diff --git a/runner.dockerfile b/runner.dockerfile index 3e7990fc..1c5d58ac 100644 --- a/runner.dockerfile +++ b/runner.dockerfile @@ -1,4 +1,4 @@ -FROM dataprocessor/hdp-cairo:v0.0.4 +FROM dataprocessor/hdp-cairo:v0.0.6 # Set shell to bash and define working directory SHELL ["/bin/bash", "-ci"]