Skip to content

Commit

Permalink
feat(sozo): add model command back (#2618)
Browse files Browse the repository at this point in the history
  • Loading branch information
glihm authored Nov 3, 2024
1 parent 2c97d56 commit 32af19e
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 191 deletions.
25 changes: 9 additions & 16 deletions bin/sozo/src/commands/call.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
use std::str::FromStr;

use anyhow::{anyhow, Result};
use clap::Args;
use dojo_types::naming;
use dojo_world::contracts::naming::ensure_namespace;
use scarb::core::Config;
use sozo_ops::resource_descriptor::ResourceDescriptor;
use sozo_scarbext::WorkspaceExt;
use starknet::core::types::{BlockId, BlockTag, Felt, FunctionCall, StarknetError};
use starknet::core::types::{BlockId, BlockTag, FunctionCall, StarknetError};
use starknet::core::utils as snutils;
use starknet::providers::{Provider, ProviderError};
use tracing::trace;

use super::execute::ContractDescriptor;
use super::options::starknet::StarknetOptions;
use super::options::world::WorldOptions;
use crate::commands::calldata_decoder;
Expand All @@ -21,7 +18,7 @@ use crate::utils;
#[command(about = "Call a system with the given calldata.")]
pub struct CallArgs {
#[arg(help = "The tag or address of the contract to call.")]
pub tag_or_address: String,
pub tag_or_address: ResourceDescriptor,

#[arg(help = "The name of the entrypoint to call.")]
pub entrypoint: String,
Expand Down Expand Up @@ -57,14 +54,7 @@ impl CallArgs {

let profile_config = ws.load_profile_config()?;

let descriptor = if utils::is_address(&self.tag_or_address) {
ContractDescriptor::Address(Felt::from_str(&self.tag_or_address)?)
} else {
ContractDescriptor::Tag(ensure_namespace(
&self.tag_or_address,
&profile_config.namespace.default,
))
};
let descriptor = self.tag_or_address.ensure_namespace(&profile_config.namespace.default);

config.tokio_handle().block_on(async {
let (world_diff, provider, _) =
Expand All @@ -77,11 +67,14 @@ impl CallArgs {
};

let contract_address = match &descriptor {
ContractDescriptor::Address(address) => Some(*address),
ContractDescriptor::Tag(tag) => {
ResourceDescriptor::Address(address) => Some(*address),
ResourceDescriptor::Tag(tag) => {
let selector = naming::compute_selector_from_tag(tag);
world_diff.get_contract_address(selector)
}
ResourceDescriptor::Name(_) => {
unimplemented!("Expected to be a resolved tag with default namespace.")
}
}
.ok_or_else(|| anyhow!("Contract {descriptor} not found in the world diff."))?;

Expand Down
40 changes: 9 additions & 31 deletions bin/sozo/src/commands/execute.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use std::fmt;
use std::str::FromStr;

use anyhow::{anyhow, Result};
use clap::Args;
use dojo_types::naming;
use dojo_utils::{Invoker, TxnConfig};
use dojo_world::contracts::naming::ensure_namespace;
use scarb::core::Config;
use sozo_ops::resource_descriptor::ResourceDescriptor;
use sozo_scarbext::WorkspaceExt;
use sozo_walnut::WalnutDebugger;
use starknet::core::types::{Call, Felt};
use starknet::core::types::Call;
use starknet::core::utils as snutils;
use tracing::trace;

Expand All @@ -26,7 +23,7 @@ pub struct ExecuteArgs {
#[arg(
help = "The address or the tag (ex: dojo_examples:actions) of the contract to be executed."
)]
pub tag_or_address: String,
pub tag_or_address: ResourceDescriptor,

#[arg(help = "The name of the entrypoint to be executed.")]
pub entrypoint: String,
Expand Down Expand Up @@ -63,14 +60,7 @@ impl ExecuteArgs {

let profile_config = ws.load_profile_config()?;

let descriptor = if utils::is_address(&self.tag_or_address) {
ContractDescriptor::Address(Felt::from_str(&self.tag_or_address)?)
} else {
ContractDescriptor::Tag(ensure_namespace(
&self.tag_or_address,
&profile_config.namespace.default,
))
};
let descriptor = self.tag_or_address.ensure_namespace(&profile_config.namespace.default);

#[cfg(feature = "walnut")]
let _walnut_debugger = WalnutDebugger::new_from_flag(
Expand All @@ -93,11 +83,14 @@ impl ExecuteArgs {
.await?;

let contract_address = match &descriptor {
ContractDescriptor::Address(address) => Some(*address),
ContractDescriptor::Tag(tag) => {
ResourceDescriptor::Address(address) => Some(*address),
ResourceDescriptor::Tag(tag) => {
let selector = naming::compute_selector_from_tag(tag);
world_diff.get_contract_address(selector)
}
ResourceDescriptor::Name(_) => {
unimplemented!("Expected to be a resolved tag with default namespace.")
}
}
.ok_or_else(|| anyhow!("Contract {descriptor} not found in the world diff."))?;

Expand Down Expand Up @@ -129,18 +122,3 @@ impl ExecuteArgs {
})
}
}

#[derive(Debug)]
pub enum ContractDescriptor {
Address(Felt),
Tag(String),
}

impl fmt::Display for ContractDescriptor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ContractDescriptor::Address(address) => write!(f, "{:#066x}", address),
ContractDescriptor::Tag(tag) => write!(f, "{}", tag),
}
}
}
6 changes: 6 additions & 0 deletions bin/sozo/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub(crate) mod hash;
pub(crate) mod init;
pub(crate) mod inspect;
pub(crate) mod migrate;
pub(crate) mod model;
pub(crate) mod options;
pub(crate) mod test;

Expand All @@ -25,6 +26,7 @@ use hash::HashArgs;
use init::InitArgs;
use inspect::InspectArgs;
use migrate::MigrateArgs;
use model::ModelArgs;
use test::TestArgs;

#[derive(Debug, Subcommand)]
Expand All @@ -48,6 +50,8 @@ pub enum Commands {
Hash(Box<HashArgs>),
#[command(about = "Initialize a new dojo project")]
Init(Box<InitArgs>),
#[command(about = "Inspect a model")]
Model(Box<ModelArgs>),
}

impl fmt::Display for Commands {
Expand All @@ -62,6 +66,7 @@ impl fmt::Display for Commands {
Commands::Test(_) => write!(f, "Test"),
Commands::Hash(_) => write!(f, "Hash"),
Commands::Init(_) => write!(f, "Init"),
Commands::Model(_) => write!(f, "Model"),
}
}
}
Expand All @@ -84,6 +89,7 @@ pub fn run(command: Commands, config: &Config) -> Result<()> {
Commands::Test(args) => args.run(config),
Commands::Hash(args) => args.run().map(|_| ()),
Commands::Init(args) => args.run(config),
Commands::Model(args) => args.run(config),
}
}

Expand Down
89 changes: 61 additions & 28 deletions bin/sozo/src/commands/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use anyhow::Result;
use clap::{Args, Subcommand};
use scarb::core::Config;
use sozo_ops::model;
use sozo_ops::resource_descriptor::ResourceDescriptor;
use sozo_scarbext::WorkspaceExt;
use starknet::core::types::Felt;
use tracing::trace;

Expand All @@ -20,7 +22,7 @@ pub enum ModelCommand {
#[command(about = "Retrieve the class hash of a model")]
ClassHash {
#[arg(help = "The tag or name of the model")]
tag_or_name: String,
tag_or_name: ResourceDescriptor,

#[command(flatten)]
world: WorldOptions,
Expand All @@ -32,7 +34,7 @@ pub enum ModelCommand {
#[command(about = "Retrieve the contract address of a model")]
ContractAddress {
#[arg(help = "The tag or name of the model")]
tag_or_name: String,
tag_or_name: ResourceDescriptor,

#[command(flatten)]
world: WorldOptions,
Expand Down Expand Up @@ -63,7 +65,7 @@ hashes, called 'hash' in the following documentation.
final storage location = hash('dojo_storage', model_selector, record_key)")]
Layout {
#[arg(help = "The tag or name of the model")]
tag_or_name: String,
tag_or_name: ResourceDescriptor,

#[command(flatten)]
world: WorldOptions,
Expand All @@ -75,7 +77,7 @@ hashes, called 'hash' in the following documentation.
#[command(about = "Retrieve the schema for a model")]
Schema {
#[arg(help = "The tag or name of the model")]
tag_or_name: String,
tag_or_name: ResourceDescriptor,

#[command(flatten)]
world: WorldOptions,
Expand All @@ -91,7 +93,7 @@ hashes, called 'hash' in the following documentation.
#[command(about = "Get a models value for the provided key")]
Get {
#[arg(help = "The tag or name of the model")]
tag_or_name: String,
tag_or_name: ResourceDescriptor,

#[arg(value_name = "KEYS")]
#[arg(value_delimiter = ',')]
Expand All @@ -109,48 +111,79 @@ hashes, called 'hash' in the following documentation.
impl ModelArgs {
pub fn run(self, config: &Config) -> Result<()> {
trace!(args = ?self);
let env_metadata = utils::load_metadata_from_config(config)?;

let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;
let profile_config = ws.load_profile_config()?;
let default_ns = profile_config.namespace.default;

config.tokio_handle().block_on(async {
match self.command {
ModelCommand::ClassHash { tag_or_name, starknet, world } => {
let tag = model::check_tag_or_read_default_namespace(&tag_or_name, config)?;
let tag = tag_or_name.ensure_namespace(&default_ns);

let (world_diff, provider, _) =
utils::get_world_diff_and_provider(starknet, world, &ws).await?;

let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_class_hash(tag, world_address, &provider).await?;
model::model_class_hash(
tag.to_string(),
world_diff.world_info.address,
&provider,
)
.await?;
Ok(())
}
ModelCommand::ContractAddress { tag_or_name, starknet, world } => {
let tag = model::check_tag_or_read_default_namespace(&tag_or_name, config)?;
let tag = tag_or_name.ensure_namespace(&default_ns);

let (world_diff, provider, _) =
utils::get_world_diff_and_provider(starknet, world, &ws).await?;

let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_contract_address(tag, world_address, &provider).await?;
model::model_contract_address(
tag.to_string(),
world_diff.world_info.address,
&provider,
)
.await?;
Ok(())
}
ModelCommand::Layout { tag_or_name, starknet, world } => {
let tag = model::check_tag_or_read_default_namespace(&tag_or_name, config)?;
let tag = tag_or_name.ensure_namespace(&default_ns);

let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_layout(tag, world_address, provider).await?;
let (world_diff, provider, _) =
utils::get_world_diff_and_provider(starknet, world, &ws).await?;

model::model_layout(tag.to_string(), world_diff.world_info.address, &provider)
.await?;
Ok(())
}
ModelCommand::Schema { tag_or_name, to_json, starknet, world } => {
let tag = model::check_tag_or_read_default_namespace(&tag_or_name, config)?;

let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_schema(tag, world_address, provider, to_json).await?;
let tag = tag_or_name.ensure_namespace(&default_ns);

let (world_diff, provider, _) =
utils::get_world_diff_and_provider(starknet, world, &ws).await?;

model::model_schema(
tag.to_string(),
world_diff.world_info.address,
&provider,
to_json,
)
.await?;
Ok(())
}
ModelCommand::Get { tag_or_name, keys, starknet, world } => {
let tag = model::check_tag_or_read_default_namespace(&tag_or_name, config)?;

let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_get(tag, keys, world_address, provider).await?;
let tag = tag_or_name.ensure_namespace(&default_ns);

let (world_diff, provider, _) =
utils::get_world_diff_and_provider(starknet, world, &ws).await?;

model::model_get(
tag.to_string(),
keys,
world_diff.world_info.address,
&provider,
)
.await?;
Ok(())
}
}
Expand Down
4 changes: 0 additions & 4 deletions bin/sozo/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,6 @@ pub fn generate_version() -> String {
version_string
}

pub fn is_address(tag_or_address: &str) -> bool {
tag_or_address.starts_with("0x")
}

/// Sets up the world diff from the environment and returns associated starknet account.
///
/// Returns the world address, the world diff, the starknet provider and the rpc url.
Expand Down
2 changes: 1 addition & 1 deletion crates/sozo/ops/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cainome.workspace = true
colored.workspace = true
colored_json.workspace = true
dojo-utils.workspace = true
dojo-types.workspace = true
dojo-world.workspace = true
futures.workspace = true
num-traits.workspace = true
Expand All @@ -35,7 +36,6 @@ assert_fs.workspace = true
dojo-test-utils = { workspace = true, features = [ "build-examples" ] }
ipfs-api-backend-hyper = { git = "https://github.com/ferristseng/rust-ipfs-api", rev = "af2c17f7b19ef5b9898f458d97a90055c3605633", features = [ "with-hyper-rustls" ] }
katana-runner.workspace = true
dojo-types.workspace = true
tokio.workspace = true
scarb.workspace = true
sozo-scarbext.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions crates/sozo/ops/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
pub mod account;
pub mod migrate;
pub mod migration_ui;
pub mod model;
pub mod resource_descriptor;

#[cfg(test)]
pub mod tests;
Loading

0 comments on commit 32af19e

Please sign in to comment.