-
Notifications
You must be signed in to change notification settings - Fork 37
feat: adding range feature for cli #497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
7a52232
5433709
cb91c45
7d17834
b15eb6b
888855e
a5fc3c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,8 @@ | |
| //! This binary demonstrates how to use the generate-pie library to generate | ||
| //! Cairo PIE files from Starknet blocks. | ||
|
|
||
| use std::collections::BTreeSet; | ||
|
|
||
| use cairo_vm::types::layout_name::LayoutName; | ||
| use clap::Parser; | ||
| use generate_pie::constants::{DEFAULT_SEPOLIA_ETH_FEE_TOKEN, DEFAULT_SEPOLIA_STRK_FEE_TOKEN}; | ||
|
|
@@ -11,15 +13,43 @@ use generate_pie::utils::load_versioned_constants; | |
| use generate_pie::{generate_pie, parse_layout}; | ||
| use log::{error, info}; | ||
|
|
||
| /// Parses a range string in format "start,end" and returns (start, end). | ||
| /// Both start and end are inclusive. | ||
| fn parse_range(range_str: &str) -> Result<(u64, u64), String> { | ||
| let parts: Vec<&str> = range_str.split(',').collect(); | ||
| if parts.len() != 2 { | ||
| return Err(format!("Invalid range format '{}'. Expected format: start,end (e.g., 1,999)", range_str)); | ||
| } | ||
|
|
||
| let start: u64 = parts[0] | ||
| .trim() | ||
| .parse() | ||
| .map_err(|_| format!("Invalid start value '{}'. Must be a positive integer.", parts[0]))?; | ||
| let end: u64 = parts[1] | ||
| .trim() | ||
| .parse() | ||
| .map_err(|_| format!("Invalid end value '{}'. Must be a positive integer.", parts[1]))?; | ||
|
|
||
| if start > end { | ||
| return Err(format!("Invalid range: start ({}) must be less than or equal to end ({})", start, end)); | ||
| } | ||
|
|
||
| Ok((start, end)) | ||
| } | ||
|
|
||
| #[derive(Parser)] | ||
| #[command(author, version, about, long_about = None)] | ||
| #[command(name = "snos")] | ||
| #[command(about = "SNOS - Starknet OS for block processing")] | ||
| struct Cli { | ||
| /// Block number(s) to process | ||
| #[arg(short, long, value_delimiter = ',', required = true, env = "SNOS_BLOCKS")] | ||
| /// Block number(s) to process (comma-separated) | ||
| #[arg(short, long, value_delimiter = ',', env = "SNOS_BLOCKS")] | ||
| blocks: Vec<u64>, | ||
|
|
||
| /// Block range to process (format: start,end - inclusive) | ||
| #[arg(short = 'R', long, env = "SNOS_RANGE")] | ||
| range: Option<String>, | ||
|
|
||
| /// RPC URL to connect to | ||
| #[arg(short, long, required = true, env = "SNOS_RPC_URL")] | ||
| rpc_url: String, | ||
|
|
@@ -82,9 +112,31 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | |
|
|
||
| info!("Starting SNOS PIE generation application"); | ||
|
|
||
| // Collect blocks from --blocks and --range arguments | ||
| let mut blocks: BTreeSet<u64> = cli.blocks.into_iter().collect(); | ||
|
|
||
| // Parse and add blocks from range if provided | ||
| if let Some(range_str) = &cli.range { | ||
| match parse_range(range_str) { | ||
| Ok((start, end)) => { | ||
| info!("Adding blocks from range {} to {} (inclusive)", start, end); | ||
| for block in start..=end { | ||
| blocks.insert(block); | ||
| } | ||
| } | ||
| Err(e) => { | ||
| error!("Range parsing error: {}", e); | ||
| std::process::exit(1); | ||
| } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic could be simplified letting CLAP managing the deserialization of the arguments by having a But the current logic works perfectly fine. 👍
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implemented: CLI now uses Option with Clap deserialization. Added test cli_parses_range_argument_into_block_range. |
||
|
|
||
| // Convert to sorted Vec | ||
| let blocks: Vec<u64> = blocks.into_iter().collect(); | ||
|
|
||
| // Validate that at least one block is provided | ||
| if cli.blocks.is_empty() { | ||
| error!("At least one block number must be provided"); | ||
| if blocks.is_empty() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be done on the
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implemented via collect_blocks: emptiness is validated on BTreeSet before conversion to Vec, with tests for merge/dedupe and empty input. |
||
| error!("At least one block number must be provided. Use --blocks and/or --range."); | ||
| std::process::exit(1); | ||
| } | ||
|
|
||
|
|
@@ -97,7 +149,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | |
| // Build the input configuration | ||
| let input = PieGenerationInput { | ||
| rpc_url: cli.rpc_url.clone(), | ||
| blocks: cli.blocks.clone(), | ||
| blocks: blocks.clone(), | ||
| chain_config: ChainConfig::new(&cli.chain, &cli.strk_fee_token_address, &cli.eth_fee_token_address, cli.is_l3), | ||
| os_hints_config: OsHintsConfiguration::default_with_is_l3(cli.is_l3), | ||
| output_path: cli.output.clone(), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented on current head: BlockRange::from_str rejects start > end and is covered by test block_range_rejects_start_greater_than_end.