From 09b00d1083ce00e5a2dbfba90eb817fdd1790de1 Mon Sep 17 00:00:00 2001 From: "remy.baranx@gmail.com" Date: Tue, 14 Jan 2025 15:47:59 +0100 Subject: [PATCH] use space instead of comma as separator --- bin/sozo/src/commands/execute.rs | 106 +++++------------- bin/sozo/src/commands/mod.rs | 2 +- .../dojo/world/src/config/calldata_decoder.rs | 4 +- 3 files changed, 32 insertions(+), 80 deletions(-) diff --git a/bin/sozo/src/commands/execute.rs b/bin/sozo/src/commands/execute.rs index 51c83d33a4..190e30cb26 100644 --- a/bin/sozo/src/commands/execute.rs +++ b/bin/sozo/src/commands/execute.rs @@ -1,5 +1,3 @@ -use std::str::FromStr; - use anyhow::{anyhow, Result}; use clap::Args; use dojo_utils::{Invoker, TxnConfig}; @@ -11,7 +9,6 @@ use sozo_scarbext::WorkspaceExt; use sozo_walnut::WalnutDebugger; use starknet::core::types::Call; use starknet::core::utils as snutils; -use starknet_crypto::Felt; use tracing::trace; use super::options::account::AccountOptions; @@ -20,40 +17,14 @@ use super::options::transaction::TransactionOptions; use super::options::world::WorldOptions; use crate::utils; -#[derive(Debug, Clone)] -pub struct CallArguments { - pub tag_or_address: ResourceDescriptor, - pub entrypoint: String, - pub calldata: Vec, -} - -impl FromStr for CallArguments { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let parts = s.splitn(3, ",").collect::>(); - - if parts.len() < 2 { - return Err(anyhow!( - "Expected call format: tag_or_address,entrypoint[,calldata1,...,calldataN]" - )); - } - - let tag_or_address = ResourceDescriptor::from_string(parts[0])?; - let entrypoint = parts[1].to_string(); - let calldata = - if parts.len() > 2 { calldata_decoder::decode_calldata(parts[2])? } else { vec![] }; - - Ok(CallArguments { tag_or_address, entrypoint, calldata }) - } -} - #[derive(Debug, Args)] #[command(about = "Execute one or several systems with the given calldata.")] pub struct ExecuteArgs { #[arg(num_args = 1..)] - #[arg(help = "A list of calls to execute.\n -A call is made up of 3 values, separated by a comma (,[,]): + #[arg(required = true)] + #[arg(help = "A list of calls to execute, separated by a /. + +A call is made up of a , an and an optional : - : the address or the tag (ex: dojo_examples-actions) of the contract to be \ called, @@ -62,7 +33,7 @@ A call is made up of 3 values, separated by a comma (,: the calldata to be passed to the system. - Comma separated values e.g., 0x12345,128,u256:9999999999. + Space separated values e.g., 0x12345 128 u256:9999999999. Sozo supports some prefixes that you can use to automatically parse some types. The supported \ prefixes are: - u256: A 256-bit unsigned integer. @@ -73,11 +44,11 @@ A call is made up of 3 values, separated by a comma (,, + pub calls: Vec, #[arg(long)] #[arg(help = "If true, sozo will compute the diff of the world from the chain to translate \ @@ -132,9 +103,11 @@ impl ExecuteArgs { let mut invoker = Invoker::new(&account, txn_config); - for call in self.calls { - let descriptor = - call.tag_or_address.ensure_namespace(&profile_config.namespace.default); + let mut arg_iter = self.calls.into_iter(); + + while let Some(arg) = arg_iter.next() { + let tag_or_address = ResourceDescriptor::from_string(&arg)?; + let descriptor = tag_or_address.ensure_namespace(&profile_config.namespace.default); let contract_address = match &descriptor { ResourceDescriptor::Address(address) => Some(*address), @@ -155,17 +128,29 @@ impl ExecuteArgs { anyhow!(message) })?; + let entrypoint = + arg_iter.next().ok_or_else(|| anyhow!("Unexpected number of arguments"))?; + + let mut calldata = vec![]; + for arg in &mut arg_iter { + let arg = match arg.as_str() { + "/" | "-" | "\\" => break, + _ => calldata_decoder::decode_single_calldata(&arg)?, + }; + calldata.extend(arg); + } + trace!( contract=?descriptor, - entrypoint=call.entrypoint, - calldata=?call.calldata, - "Executing Execute command." + entrypoint=entrypoint, + calldata=?calldata, + "Decoded call." ); invoker.add_call(Call { to: contract_address, - selector: snutils::get_selector_from_name(&call.entrypoint)?, - calldata: call.calldata, + selector: snutils::get_selector_from_name(&entrypoint)?, + calldata, }); } @@ -181,36 +166,3 @@ impl ExecuteArgs { }) } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_call_arguments_from_str() { - let res = CallArguments::from_str("0x1234,run").unwrap(); - assert!(res.tag_or_address == ResourceDescriptor::from_string("0x1234").unwrap()); - assert!(res.entrypoint == "run"); - - let res = CallArguments::from_str("dojo-Player,run").unwrap(); - assert!(res.tag_or_address == ResourceDescriptor::from_string("dojo-Player").unwrap()); - assert!(res.entrypoint == "run"); - - let res = CallArguments::from_str("Player,run").unwrap(); - assert!(res.tag_or_address == ResourceDescriptor::from_string("Player").unwrap()); - assert!(res.entrypoint == "run"); - - let res = CallArguments::from_str("0x1234,run,1,2,3").unwrap(); - assert!(res.tag_or_address == ResourceDescriptor::from_string("0x1234").unwrap()); - assert!(res.entrypoint == "run"); - assert!(res.calldata == vec![Felt::ONE, Felt::TWO, Felt::THREE]); - - // missing entry point - let res = CallArguments::from_str("0x1234"); - assert!(res.is_err()); - - // bad tag_or_address format - let res = CallArguments::from_str("0x12X4,run"); - assert!(res.is_err()); - } -} diff --git a/bin/sozo/src/commands/mod.rs b/bin/sozo/src/commands/mod.rs index 0170c6bc30..43a5b3f688 100644 --- a/bin/sozo/src/commands/mod.rs +++ b/bin/sozo/src/commands/mod.rs @@ -49,7 +49,7 @@ pub enum Commands { #[command(about = "Run a migration, declaring and deploying contracts as necessary to update \ the world")] Migrate(Box), - #[command(about = "Execute a system with the given calldata.")] + #[command(about = "Execute one or several systems with the given calldata.")] Execute(Box), #[command(about = "Inspect the world")] Inspect(Box), diff --git a/crates/dojo/world/src/config/calldata_decoder.rs b/crates/dojo/world/src/config/calldata_decoder.rs index fd74e0aa46..15d87112ad 100644 --- a/crates/dojo/world/src/config/calldata_decoder.rs +++ b/crates/dojo/world/src/config/calldata_decoder.rs @@ -140,7 +140,7 @@ pub fn decode_calldata(input: &str) -> DecoderResult> { let mut calldata = vec![]; for item in items { - calldata.extend(decode_inner(item)?); + calldata.extend(decode_single_calldata(item)?); } Ok(calldata) @@ -154,7 +154,7 @@ pub fn decode_calldata(input: &str) -> DecoderResult> { /// /// # Returns /// A vector of [`Felt`]s. -fn decode_inner(item: &str) -> DecoderResult> { +pub fn decode_single_calldata(item: &str) -> DecoderResult> { let item = item.trim(); let felts = if let Some((prefix, value)) = item.split_once(ITEM_PREFIX_DELIMITER) {