Skip to content
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

feat(sozo): add model command back #2618

Merged
merged 2 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
#[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,

Check warning on line 21 in bin/sozo/src/commands/call.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/call.rs#L21

Added line #L21 was not covered by tests

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

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);

Check warning on line 57 in bin/sozo/src/commands/call.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/call.rs#L57

Added line #L57 was not covered by tests

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

let contract_address = match &descriptor {
ContractDescriptor::Address(address) => Some(*address),
ContractDescriptor::Tag(tag) => {
ResourceDescriptor::Address(address) => Some(*address),
ResourceDescriptor::Tag(tag) => {

Check warning on line 71 in bin/sozo/src/commands/call.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/call.rs#L70-L71

Added lines #L70 - L71 were not covered by tests
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.")

Check warning on line 76 in bin/sozo/src/commands/call.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/call.rs#L76

Added line #L76 was not covered by tests
}
Comment on lines +75 to +77
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle ResourceDescriptor::Name to prevent runtime panics

Ohayo sensei! Using unimplemented! for the ResourceDescriptor::Name variant will cause a panic if encountered at runtime. It's recommended to handle this variant properly or return a descriptive error to prevent unexpected crashes.

Apply this diff to handle the variant:

 ResourceDescriptor::Name(_) => {
-    unimplemented!("Expected to be a resolved tag with default namespace.")
+    return Err(anyhow!(
+        "Expected a resolved tag with default namespace for descriptor: {}",
+        descriptor
+    ));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ResourceDescriptor::Name(_) => {
unimplemented!("Expected to be a resolved tag with default namespace.")
}
ResourceDescriptor::Name(_) => {
return Err(anyhow!(
"Expected a resolved tag with default namespace for descriptor: {}",
descriptor
));
}

}
.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 @@
#[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,

Check warning on line 26 in bin/sozo/src/commands/execute.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L26

Added line #L26 was not covered by tests

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

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);

Check warning on line 63 in bin/sozo/src/commands/execute.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L63

Added line #L63 was not covered by tests

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

let contract_address = match &descriptor {
ContractDescriptor::Address(address) => Some(*address),
ContractDescriptor::Tag(tag) => {
ResourceDescriptor::Address(address) => Some(*address),
ResourceDescriptor::Tag(tag) => {

Check warning on line 87 in bin/sozo/src/commands/execute.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L86-L87

Added lines #L86 - L87 were not covered by tests
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.")

Check warning on line 92 in bin/sozo/src/commands/execute.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L92

Added line #L92 was not covered by tests
}
Comment on lines +91 to +93
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ohayo, sensei! Replace unimplemented!() with proper error handling

Using unimplemented!() will cause a panic at runtime if ResourceDescriptor::Name(_) is encountered. This is not ideal in production code as it can lead to unexpected crashes. Consider returning a descriptive error to handle this case gracefully.

Apply this diff to handle the error appropriately:

 ResourceDescriptor::Name(_) => {
-    unimplemented!("Expected to be a resolved tag with default namespace.")
+    return Err(anyhow!(
+        "Unresolved resource descriptor: expected a resolved tag with default namespace."
+    ));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ResourceDescriptor::Name(_) => {
unimplemented!("Expected to be a resolved tag with default namespace.")
}
ResourceDescriptor::Name(_) => {
return Err(anyhow!(
"Unresolved resource descriptor: expected 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 @@
})
}
}

#[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 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 init::InitArgs;
use inspect::InspectArgs;
use migrate::MigrateArgs;
use model::ModelArgs;
use test::TestArgs;

#[derive(Debug, Subcommand)]
Expand All @@ -48,6 +50,8 @@
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 @@
Commands::Test(_) => write!(f, "Test"),
Commands::Hash(_) => write!(f, "Hash"),
Commands::Init(_) => write!(f, "Init"),
Commands::Model(_) => write!(f, "Model"),

Check warning on line 69 in bin/sozo/src/commands/mod.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/mod.rs#L69

Added line #L69 was not covered by tests
}
}
}
Expand All @@ -84,6 +89,7 @@
Commands::Test(args) => args.run(config),
Commands::Hash(args) => args.run().map(|_| ()),
Commands::Init(args) => args.run(config),
Commands::Model(args) => args.run(config),

Check warning on line 92 in bin/sozo/src/commands/mod.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/mod.rs#L92

Added line #L92 was not covered by tests
}
}

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 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 @@
#[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,

Check warning on line 25 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L25

Added line #L25 was not covered by tests

#[command(flatten)]
world: WorldOptions,
Expand All @@ -32,7 +34,7 @@
#[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,

Check warning on line 37 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L37

Added line #L37 was not covered by tests

#[command(flatten)]
world: WorldOptions,
Expand Down Expand Up @@ -63,7 +65,7 @@
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,

Check warning on line 68 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L68

Added line #L68 was not covered by tests

#[command(flatten)]
world: WorldOptions,
Expand All @@ -75,7 +77,7 @@
#[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,

Check warning on line 80 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L80

Added line #L80 was not covered by tests

#[command(flatten)]
world: WorldOptions,
Expand All @@ -91,7 +93,7 @@
#[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,

Check warning on line 96 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L96

Added line #L96 was not covered by tests

#[arg(value_name = "KEYS")]
#[arg(value_delimiter = ',')]
Expand All @@ -109,48 +111,79 @@
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;

Check warning on line 117 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L115-L117

Added lines #L115 - L117 were not covered by tests

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);

Check warning on line 122 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L122

Added line #L122 was not covered by tests

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

Check warning on line 125 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L124-L125

Added lines #L124 - L125 were not covered by tests

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?;

Check warning on line 132 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L127-L132

Added lines #L127 - L132 were not covered by tests
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);

Check warning on line 136 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L136

Added line #L136 was not covered by tests

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

Check warning on line 139 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L138-L139

Added lines #L138 - L139 were not covered by tests

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?;

Check warning on line 146 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L141-L146

Added lines #L141 - L146 were not covered by tests
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);

Check warning on line 150 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L150

Added line #L150 was not covered by tests

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?;

Check warning on line 153 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L152-L153

Added lines #L152 - L153 were not covered by tests

model::model_layout(tag.to_string(), world_diff.world_info.address, &provider)
.await?;

Check warning on line 156 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L155-L156

Added lines #L155 - L156 were not covered by tests
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);

Check warning on line 160 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L160

Added line #L160 was not covered by tests

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

Check warning on line 163 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L162-L163

Added lines #L162 - L163 were not covered by tests

model::model_schema(
tag.to_string(),
world_diff.world_info.address,
&provider,
to_json,
)
.await?;

Check warning on line 171 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L165-L171

Added lines #L165 - L171 were not covered by tests
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);

Check warning on line 175 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L175

Added line #L175 was not covered by tests

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

Check warning on line 178 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L177-L178

Added lines #L177 - L178 were not covered by tests

model::model_get(
tag.to_string(),
keys,
world_diff.world_info.address,
&provider,
)
.await?;

Check warning on line 186 in bin/sozo/src/commands/model.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/model.rs#L180-L186

Added lines #L180 - L186 were not covered by tests
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
Loading