Skip to content

Commit

Permalink
use space instead of comma as separator
Browse files Browse the repository at this point in the history
  • Loading branch information
remybar committed Jan 14, 2025
1 parent ad1ce8b commit 5ee7a30
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 82 deletions.
106 changes: 29 additions & 77 deletions bin/sozo/src/commands/execute.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::str::FromStr;

use anyhow::{anyhow, Result};
use clap::Args;
use dojo_utils::{Invoker, TxnConfig};
Expand All @@ -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;
Expand All @@ -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<Felt>,
}

impl FromStr for CallArguments {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self> {
let parts = s.splitn(3, ",").collect::<Vec<_>>();

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 (<TAG_OR_ADDRESS>,<ENTRYPOINT>[,<CALLDATA>]):
#[arg(required = true)]
#[arg(help = "A list of calls to execute, separated by a /.
A call is made up of a <TAG_OR_ADDRESS>, an <ENTRYPOINT> and an optional <CALLDATA>:
- <TAG_OR_ADDRESS>: the address or the tag (ex: dojo_examples-actions) of the contract to be \
called,
Expand All @@ -62,7 +33,7 @@ A call is made up of 3 values, separated by a comma (<TAG_OR_ADDRESS>,<ENTRYPOIN
- <CALLDATA>: 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.
Expand All @@ -73,11 +44,11 @@ A call is made up of 3 values, separated by a comma (<TAG_OR_ADDRESS>,<ENTRYPOIN
EXAMPLE
sozo execute 0x1234,run ns-Actions,move,1,2
sozo execute 0x1234 run / ns-Actions move 1 2
Executes the run function of the contract at the address 0x1234 without calldata,
and the move function of the ns-Actions contract, with the calldata [1,2].")]
pub calls: Vec<CallArguments>,
pub calls: Vec<String>,

#[arg(long)]
#[arg(help = "If true, sozo will compute the diff of the world from the chain to translate \
Expand Down Expand Up @@ -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),
Expand All @@ -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,
});
}

Expand All @@ -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());
}
}
8 changes: 5 additions & 3 deletions bin/sozo/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ pub enum Commands {
Build(Box<BuildArgs>),
#[command(about = "Build and migrate the world every time a file changes")]
Dev(Box<DevArgs>),
#[command(about = "Run a migration, declaring and deploying contracts as necessary to update \
the world")]
#[command(
about = "Run a migration, declaring and deploying contracts as necessary to update \
the world"
)]
Migrate(Box<MigrateArgs>),
#[command(about = "Execute a system with the given calldata.")]
#[command(about = "Execute one or several systems with the given calldata.")]
Execute(Box<ExecuteArgs>),
#[command(about = "Inspect the world")]
Inspect(Box<InspectArgs>),
Expand Down
4 changes: 2 additions & 2 deletions crates/dojo/world/src/config/calldata_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ pub fn decode_calldata(input: &str) -> DecoderResult<Vec<Felt>> {
let mut calldata = vec![];

for item in items {
calldata.extend(decode_inner(item)?);
calldata.extend(decode_single_calldata(item)?);
}

Ok(calldata)
Expand All @@ -154,7 +154,7 @@ pub fn decode_calldata(input: &str) -> DecoderResult<Vec<Felt>> {
///
/// # Returns
/// A vector of [`Felt`]s.
fn decode_inner(item: &str) -> DecoderResult<Vec<Felt>> {
pub fn decode_single_calldata(item: &str) -> DecoderResult<Vec<Felt>> {
let item = item.trim();

let felts = if let Some((prefix, value)) = item.split_once(ITEM_PREFIX_DELIMITER) {
Expand Down

0 comments on commit 5ee7a30

Please sign in to comment.