From 98801d3dc313b9cb5fb29a8fa99fb6f9ceb33929 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 17 Jul 2024 13:50:37 +0200 Subject: [PATCH 01/35] feat(torii-core): store update member --- bin/torii/src/main.rs | 2 + crates/torii/core/src/processors/mod.rs | 1 + .../src/processors/store_update_member.rs | 84 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 crates/torii/core/src/processors/store_update_member.rs diff --git a/bin/torii/src/main.rs b/bin/torii/src/main.rs index 27731e05a4..d9035fc612 100644 --- a/bin/torii/src/main.rs +++ b/bin/torii/src/main.rs @@ -33,6 +33,7 @@ use torii_core::processors::register_model::RegisterModelProcessor; use torii_core::processors::store_del_record::StoreDelRecordProcessor; use torii_core::processors::store_set_record::StoreSetRecordProcessor; use torii_core::processors::store_transaction::StoreTransactionProcessor; +use torii_core::processors::store_update_member::StoreUpdateMemberProcessor; use torii_core::processors::store_update_record::StoreUpdateRecordProcessor; use torii_core::simple_broker::SimpleBroker; use torii_core::sql::Sql; @@ -172,6 +173,7 @@ async fn main() -> anyhow::Result<()> { Box::new(StoreDelRecordProcessor), Box::new(EventMessageProcessor), Box::new(StoreUpdateRecordProcessor), + Box::new(StoreUpdateMemberProcessor), ], transaction: vec![Box::new(StoreTransactionProcessor)], ..Processors::default() diff --git a/crates/torii/core/src/processors/mod.rs b/crates/torii/core/src/processors/mod.rs index 6f53b567dc..f69f2de55e 100644 --- a/crates/torii/core/src/processors/mod.rs +++ b/crates/torii/core/src/processors/mod.rs @@ -13,6 +13,7 @@ pub mod store_del_record; pub mod store_set_record; pub mod store_transaction; pub mod store_update_record; +pub mod store_update_member; const MODEL_INDEX: usize = 0; const NUM_KEYS_INDEX: usize = 1; diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs new file mode 100644 index 0000000000..1875a88b8e --- /dev/null +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -0,0 +1,84 @@ +use anyhow::{Context, Error, Ok, Result}; +use async_trait::async_trait; +use dojo_world::contracts::model::ModelReader; +use dojo_world::contracts::naming; +use dojo_world::contracts::world::WorldContractReader; +use num_traits::ToPrimitive; +use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; +use starknet::providers::Provider; +use tracing::info; + +use super::EventProcessor; +use crate::processors::{ENTITY_ID_INDEX, MODEL_INDEX}; +use crate::sql::Sql; + +pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record"; + +#[derive(Default, Debug)] +pub struct StoreUpdateMemberProcessor; + +#[async_trait] +impl

EventProcessor

for StoreUpdateMemberProcessor +where + P: Provider + Send + Sync + std::fmt::Debug, +{ + fn event_key(&self) -> String { + "StoreUpdateMember".to_string() + } + + fn validate(&self, event: &Event) -> bool { + if event.keys.len() > 1 { + info!( + target: LOG_TARGET, + event_key = %>::event_key(self), + invalid_keys = %>::event_keys_as_string(self, event), + "Invalid event keys." + ); + return false; + } + true + } + + async fn process( + &self, + _world: &WorldContractReader

, + db: &mut Sql, + _block_number: u64, + block_timestamp: u64, + _transaction_receipt: &TransactionReceiptWithBlockInfo, + event_id: &str, + event: &Event, + ) -> Result<(), Error> { + let selector = event.data[MODEL_INDEX]; + let entity_id = event.data[ENTITY_ID_INDEX]; + + let model = db.model(selector).await?; + + info!( + target: LOG_TARGET, + name = %model.name(), + entity_id = format!("{:#x}", entity_id), + "Store update record.", + ); + + let values_start = ENTITY_ID_INDEX + 1; + let values_end: usize = + values_start + event.data[values_start].to_usize().context("invalid usize")?; + + // Skip the length to only get the values as they will be deserialized. + let values = event.data[values_start + 1..=values_end].to_vec(); + + let tag = naming::get_tag(model.namespace(), model.name()); + + // Keys are read from the db, since we don't have access to them when only + // the entity id is passed. + let keys = db.get_entity_keys(entity_id, &tag).await?; + let mut keys_and_unpacked = [keys, values].concat(); + + let mut entity = model.schema().await?; + entity.deserialize(&mut keys_and_unpacked)?; + + db.set_entity(entity, event_id, block_timestamp).await?; + Ok(()) + } +} From 3f6908e4387bea16a6987d3637695251f3f749f9 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 17 Jul 2024 14:18:18 +0200 Subject: [PATCH 02/35] feat; add set_model_member for updating specific member --- .../src/processors/store_update_member.rs | 29 ++++++++++++----- crates/torii/core/src/sql.rs | 31 +++++++++++++++++-- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 1875a88b8e..46f2c706ec 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -1,10 +1,11 @@ -use anyhow::{Context, Error, Ok, Result}; +use anyhow::{Context, Error, Result}; use async_trait::async_trait; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::naming; use dojo_world::contracts::world::WorldContractReader; use num_traits::ToPrimitive; use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; +use starknet::core::utils::get_selector_from_name; use starknet::providers::Provider; use tracing::info; @@ -14,6 +15,8 @@ use crate::sql::Sql; pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record"; +const MEMBER_INDEX: usize = 2; + #[derive(Default, Debug)] pub struct StoreUpdateMemberProcessor; @@ -46,11 +49,12 @@ where _block_number: u64, block_timestamp: u64, _transaction_receipt: &TransactionReceiptWithBlockInfo, - event_id: &str, + _event_id: &str, event: &Event, ) -> Result<(), Error> { let selector = event.data[MODEL_INDEX]; let entity_id = event.data[ENTITY_ID_INDEX]; + let member_selector = event.data[MEMBER_INDEX]; let model = db.model(selector).await?; @@ -61,7 +65,7 @@ where "Store update record.", ); - let values_start = ENTITY_ID_INDEX + 1; + let values_start = MEMBER_INDEX + 1; let values_end: usize = values_start + event.data[values_start].to_usize().context("invalid usize")?; @@ -75,10 +79,21 @@ where let keys = db.get_entity_keys(entity_id, &tag).await?; let mut keys_and_unpacked = [keys, values].concat(); - let mut entity = model.schema().await?; - entity.deserialize(&mut keys_and_unpacked)?; + let schema = model.schema().await?; + let mut ty = schema + .as_struct() + .expect("model schema must be a struct") + .children + .iter() + .find(|c| { + get_selector_from_name(&c.name).expect("invalid selector for member name") + == member_selector + }) + .context("member not found")? + .ty + .clone(); + ty.deserialize(&mut keys_and_unpacked)?; - db.set_entity(entity, event_id, block_timestamp).await?; - Ok(()) + db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 69edbc3d70..16373cc637 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -271,6 +271,29 @@ impl Sql { Ok(()) } + pub async fn set_model_member( + &mut self, + entity_id: Felt, + model_tag: &str, + member: &Ty, + block_timestamp: u64, + ) -> Result<()> { + let entity_id = format!("{:#x}", entity_id); + let path = vec![model_tag.to_string()]; + // update model member + self.build_set_entity_queries_recursive( + path, + &entity_id, + (&entity_id, false), + member, + block_timestamp, + &vec![], + ); + self.query_queue.execute_all().await?; + + Ok(()) + } + pub async fn delete_entity(&mut self, entity_id: Felt, entity: Ty) -> Result<()> { let entity_id = format!("{:#x}", entity_id); let path = vec![entity.name()]; @@ -556,7 +579,7 @@ impl Sql { } } - fn build_set_entity_queries_recursive( + pub fn build_set_entity_queries_recursive( &mut self, path: Vec, event_id: &str, @@ -658,7 +681,11 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } + if let Ty::Tuple(t) = &o.ty { + t.is_empty() + } else { + false + } }, ) { return; From 8aba41cd07bd412a4fca0218b6e7de27583b9711 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 17 Jul 2024 16:52:30 +0100 Subject: [PATCH 03/35] chore: format --- crates/torii/core/src/processors/mod.rs | 2 +- crates/torii/core/src/sql.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/torii/core/src/processors/mod.rs b/crates/torii/core/src/processors/mod.rs index f69f2de55e..e2b22e4d75 100644 --- a/crates/torii/core/src/processors/mod.rs +++ b/crates/torii/core/src/processors/mod.rs @@ -12,8 +12,8 @@ pub mod register_model; pub mod store_del_record; pub mod store_set_record; pub mod store_transaction; -pub mod store_update_record; pub mod store_update_member; +pub mod store_update_record; const MODEL_INDEX: usize = 0; const NUM_KEYS_INDEX: usize = 1; diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 16373cc637..cf2f3b9378 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -681,11 +681,7 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { - t.is_empty() - } else { - false - } + if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } }, ) { return; From 65b2c39db31e68ad59fb987df391d1d4a6c8b4e8 Mon Sep 17 00:00:00 2001 From: Larko <59736843+Larkooo@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:55:12 +0200 Subject: [PATCH 04/35] chore: update log to include member nname --- .../src/processors/store_update_member.rs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 46f2c706ec..89873b24ff 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -57,12 +57,26 @@ where let member_selector = event.data[MEMBER_INDEX]; let model = db.model(selector).await?; + let schema = model.schema().await?; + let mut ty = schema + .as_struct() + .expect("model schema must be a struct") + .children + .iter() + .find(|c| { + get_selector_from_name(&c.name).expect("invalid selector for member name") + == member_selector + }) + .context("member not found")? + .ty + .clone(); info!( target: LOG_TARGET, name = %model.name(), entity_id = format!("{:#x}", entity_id), - "Store update record.", + member = %ty.name(), + "Store update member.", ); let values_start = MEMBER_INDEX + 1; @@ -79,21 +93,8 @@ where let keys = db.get_entity_keys(entity_id, &tag).await?; let mut keys_and_unpacked = [keys, values].concat(); - let schema = model.schema().await?; - let mut ty = schema - .as_struct() - .expect("model schema must be a struct") - .children - .iter() - .find(|c| { - get_selector_from_name(&c.name).expect("invalid selector for member name") - == member_selector - }) - .context("member not found")? - .ty - .clone(); + ty.deserialize(&mut keys_and_unpacked)?; - db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await } } From b54901c46f82d6c24f88fe47fdba15b7e515c453 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 17 Jul 2024 23:51:07 +0100 Subject: [PATCH 05/35] fmt --- crates/torii/core/src/processors/store_update_member.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 89873b24ff..73a9b7575e 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -93,7 +93,6 @@ where let keys = db.get_entity_keys(entity_id, &tag).await?; let mut keys_and_unpacked = [keys, values].concat(); - ty.deserialize(&mut keys_and_unpacked)?; db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await } From 349b32731e023639dbaaac262f97dcc47c45a41b Mon Sep 17 00:00:00 2001 From: Nasr Date: Thu, 18 Jul 2024 00:04:45 +0100 Subject: [PATCH 06/35] refactor: clean code & add is event message --- .../core/src/processors/store_update_member.rs | 4 ++-- crates/torii/core/src/sql.rs | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 73a9b7575e..9ef053c1fc 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -49,7 +49,7 @@ where _block_number: u64, block_timestamp: u64, _transaction_receipt: &TransactionReceiptWithBlockInfo, - _event_id: &str, + event_id: &str, event: &Event, ) -> Result<(), Error> { let selector = event.data[MODEL_INDEX]; @@ -94,6 +94,6 @@ where let mut keys_and_unpacked = [keys, values].concat(); ty.deserialize(&mut keys_and_unpacked)?; - db.set_model_member(entity_id, &schema.name(), &ty, block_timestamp).await + db.set_model_member(entity_id, false, &schema.name(), &ty, event_id, block_timestamp).await } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index cf2f3b9378..d3e7073780 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -23,6 +23,8 @@ use crate::types::{ }; use crate::utils::{must_utc_datetime_from_timestamp, utc_dt_string_from_timestamp}; +type IsEventMessage = bool; + pub const FELT_DELIMITER: &str = "/"; #[cfg(test)] @@ -274,8 +276,10 @@ impl Sql { pub async fn set_model_member( &mut self, entity_id: Felt, + is_event_message: bool, model_tag: &str, member: &Ty, + event_id: &str, block_timestamp: u64, ) -> Result<()> { let entity_id = format!("{:#x}", entity_id); @@ -283,8 +287,8 @@ impl Sql { // update model member self.build_set_entity_queries_recursive( path, - &entity_id, - (&entity_id, false), + event_id, + (&entity_id, is_event_message), member, block_timestamp, &vec![], @@ -584,7 +588,7 @@ impl Sql { path: Vec, event_id: &str, // The id of the entity and if the entity is an event message - entity_id: (&str, bool), + entity_id: (&str, IsEventMessage), entity: &Ty, block_timestamp: u64, indexes: &Vec, @@ -681,7 +685,11 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } + if let Ty::Tuple(t) = &o.ty { + t.is_empty() + } else { + false + } }, ) { return; From 9dd48d877df6cc6bc56004f259a97d72d99243d7 Mon Sep 17 00:00:00 2001 From: Nasr Date: Thu, 18 Jul 2024 00:24:28 +0100 Subject: [PATCH 07/35] fmt --- crates/torii/core/src/sql.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index d3e7073780..6fbabc6217 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -685,11 +685,7 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { - t.is_empty() - } else { - false - } + if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } }, ) { return; From b0d9fd51abc28ed3eaa8d022cb8d5733b7164f5c Mon Sep 17 00:00:00 2001 From: Nasr Date: Thu, 18 Jul 2024 00:25:54 +0100 Subject: [PATCH 08/35] chore --- crates/torii/core/src/sql.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 6fbabc6217..339b5f2f41 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -583,7 +583,7 @@ impl Sql { } } - pub fn build_set_entity_queries_recursive( + fn build_set_entity_queries_recursive( &mut self, path: Vec, event_id: &str, From 71af00187779b7cd799af97c2d14120cae4553e4 Mon Sep 17 00:00:00 2001 From: glihm Date: Thu, 18 Jul 2024 08:31:19 -0600 Subject: [PATCH 09/35] feat: emit the store member update from the world --- Cargo.lock | 37 +++++++------- crates/dojo-core/src/world.cairo | 17 +++++-- .../manifests/dev/base/abis/dojo-world.json | 32 +++++++++++++ .../manifests/dev/base/dojo-world.toml | 4 +- crates/dojo-world/src/contracts/abi/world.rs | 32 +++++++++++++ .../src/processors/store_update_member.rs | 2 +- examples/spawn-and-move/Scarb.toml | 2 +- .../manifests/dev/base/abis/dojo-world.json | 32 +++++++++++++ .../manifests/dev/base/dojo-world.toml | 4 +- .../dev/deployment/abis/dojo-world.json | 32 +++++++++++++ .../manifests/dev/deployment/manifest.json | 48 +++++++++++++++---- .../manifests/dev/deployment/manifest.toml | 16 +++---- .../release/base/abis/dojo-world.json | 32 +++++++++++++ .../manifests/release/base/dojo-world.toml | 4 +- 14 files changed, 249 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58b7530eda..7fea87cf75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6e6436a9530f25010d13653e206fab4c9feddacf21a54de8d7311b275bc56b" +checksum = "413902aa18a97569e60f679c23f46a18db1656d87ab4d4e49d0e1e52042f66df" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaeaccd50238126e3a0ff9387c7c568837726ad4f4e399b528ca88104d6c25ef" +checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -401,9 +401,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f783611babedbbe90db3478c120fb5f5daacceffc210b39adc0af4fe0da70bad" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", @@ -666,9 +666,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bad41a7c19498e3f6079f7744656328699f8ea3e783bdd10d85788cd439f572" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -680,9 +680,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9899da7d011b4fe4c406a524ed3e3f963797dbc93b45479d60341d3a27b252" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", @@ -699,9 +699,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32d595768fdc61331a132b6f65db41afae41b9b97d36c21eb1b955c422a7e60" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" dependencies = [ "alloy-json-abi", "const-hex", @@ -716,18 +716,19 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa2fbd22d353d8685bd9fee11ba2d8b5c3b1d11e56adb3265fcf1f32bfdf404" +checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ + "serde", "winnow 0.6.13", ] [[package]] name = "alloy-sol-types" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49042c6d3b66a9fe6b2b5a8bf0d39fc2ae1ee0310a2a26ffedd79fb097878dd" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -14047,9 +14048,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d71e19bca02c807c9faa67b5a47673ff231b6e7449b251695188522f1dc44b2" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" dependencies = [ "paste", "proc-macro2", diff --git a/crates/dojo-core/src/world.cairo b/crates/dojo-core/src/world.cairo index 0c88c9ac15..2107bafca0 100644 --- a/crates/dojo-core/src/world.cairo +++ b/crates/dojo-core/src/world.cairo @@ -156,6 +156,7 @@ mod world { ModelRegistered: ModelRegistered, StoreSetRecord: StoreSetRecord, StoreUpdateRecord: StoreUpdateRecord, + StoreUpdateMember: StoreUpdateMember, StoreDelRecord: StoreDelRecord, WriterUpdated: WriterUpdated, OwnerUpdated: OwnerUpdated, @@ -230,6 +231,14 @@ mod world { values: Span, } + #[derive(Drop, starknet::Event)] + struct StoreUpdateMember { + table: felt252, + entity_id: felt252, + member_selector: felt252, + values: Span, + } + #[derive(Drop, starknet::Event)] struct StoreDelRecord { table: felt252, @@ -860,10 +869,12 @@ mod world { ); }, ModelIndex::MemberId(( - entity_id, member_id + entity_id, member_selector )) => { - self._write_model_member(model_selector, entity_id, member_id, values, layout); - // TODO: here we need a new event update and see how Torii can process that. + self._write_model_member(model_selector, entity_id, member_selector, values, layout); + EventEmitter::emit( + ref self, StoreUpdateMember { table: model_selector, entity_id, member_selector, values } + ); } } } diff --git a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json index fe02b53f14..48a015a203 100644 --- a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json +++ b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world::StoreDelRecord", @@ -1156,6 +1183,11 @@ "type": "dojo::world::world::StoreUpdateRecord", "kind": "nested" }, + { + "name": "StoreUpdateMember", + "type": "dojo::world::world::StoreUpdateMember", + "kind": "nested" + }, { "name": "StoreDelRecord", "type": "dojo::world::world::StoreDelRecord", diff --git a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml index e79e888f02..0414ddfd99 100644 --- a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml +++ b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" -original_class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" +class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" +original_class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" abi = "manifests/dev/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" diff --git a/crates/dojo-world/src/contracts/abi/world.rs b/crates/dojo-world/src/contracts/abi/world.rs index f4a86c7a37..2fb52796c3 100644 --- a/crates/dojo-world/src/contracts/abi/world.rs +++ b/crates/dojo-world/src/contracts/abi/world.rs @@ -981,6 +981,33 @@ abigen!( } ] }, + { + "type": "event", + "name": "dojo::world::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world::StoreDelRecord", @@ -1162,6 +1189,11 @@ abigen!( "type": "dojo::world::world::StoreUpdateRecord", "kind": "nested" }, + { + "name": "StoreUpdateMember", + "type": "dojo::world::world::StoreUpdateMember", + "kind": "nested" + }, { "name": "StoreDelRecord", "type": "dojo::world::world::StoreDelRecord", diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 9ef053c1fc..73a6752aff 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -13,7 +13,7 @@ use super::EventProcessor; use crate::processors::{ENTITY_ID_INDEX, MODEL_INDEX}; use crate::sql::Sql; -pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record"; +pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_member"; const MEMBER_INDEX: usize = 2; diff --git a/examples/spawn-and-move/Scarb.toml b/examples/spawn-and-move/Scarb.toml index 39f63432ab..6e68cc902b 100644 --- a/examples/spawn-and-move/Scarb.toml +++ b/examples/spawn-and-move/Scarb.toml @@ -43,7 +43,7 @@ rpc_url = "http://localhost:5050/" # Default account for katana with seed = 0 account_address = "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03" private_key = "0x1800000000300000180000000000030000000000003006001800006600" -world_address = "0x5377ecb8b7b6ce3f17daf9064a5f5ee7f6642c3e72579b45478a828007db355" +world_address = "0x36d0f2bb88ec90b2eb4b3ae2dae98372c5c27fead89fb6cf4d5a43231e90d2f" [profile.release.tool.dojo] # for more info on how `merge-strategy` works see: diff --git a/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json b/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json index fe02b53f14..48a015a203 100644 --- a/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world::StoreDelRecord", @@ -1156,6 +1183,11 @@ "type": "dojo::world::world::StoreUpdateRecord", "kind": "nested" }, + { + "name": "StoreUpdateMember", + "type": "dojo::world::world::StoreUpdateMember", + "kind": "nested" + }, { "name": "StoreDelRecord", "type": "dojo::world::world::StoreDelRecord", diff --git a/examples/spawn-and-move/manifests/dev/base/dojo-world.toml b/examples/spawn-and-move/manifests/dev/base/dojo-world.toml index e79e888f02..0414ddfd99 100644 --- a/examples/spawn-and-move/manifests/dev/base/dojo-world.toml +++ b/examples/spawn-and-move/manifests/dev/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" -original_class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" +class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" +original_class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" abi = "manifests/dev/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" diff --git a/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json b/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json index fe02b53f14..48a015a203 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world::StoreDelRecord", @@ -1156,6 +1183,11 @@ "type": "dojo::world::world::StoreUpdateRecord", "kind": "nested" }, + { + "name": "StoreUpdateMember", + "type": "dojo::world::world::StoreUpdateMember", + "kind": "nested" + }, { "name": "StoreDelRecord", "type": "dojo::world::world::StoreDelRecord", diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.json b/examples/spawn-and-move/manifests/dev/deployment/manifest.json index ce9072be7e..f456a3cc3e 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.json +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.json @@ -1,8 +1,8 @@ { "world": { "kind": "WorldContract", - "class_hash": "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557", - "original_class_hash": "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557", + "class_hash": "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820", + "original_class_hash": "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820", "abi": [ { "type": "impl", @@ -980,6 +980,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world::StoreDelRecord", @@ -1161,6 +1188,11 @@ "type": "dojo::world::world::StoreUpdateRecord", "kind": "nested" }, + { + "name": "StoreUpdateMember", + "type": "dojo::world::world::StoreUpdateMember", + "kind": "nested" + }, { "name": "StoreDelRecord", "type": "dojo::world::world::StoreDelRecord", @@ -1189,8 +1221,8 @@ ] } ], - "address": "0x5377ecb8b7b6ce3f17daf9064a5f5ee7f6642c3e72579b45478a828007db355", - "transaction_hash": "0x59c745b80871acdab7ad1c29703cac9aa949f4326b32037943512adc0a19ab2", + "address": "0x36d0f2bb88ec90b2eb4b3ae2dae98372c5c27fead89fb6cf4d5a43231e90d2f", + "transaction_hash": "0x2a49aacf9d50af1268a841c07cc6e014825a2be95f89d5ce8e61fc2895cce9d", "block_number": 3, "seed": "dojo_examples", "metadata": { @@ -1210,7 +1242,7 @@ "contracts": [ { "kind": "DojoContract", - "address": "0x5c92c8995272a6ae073392c6878fe80cd71ae0be4931bce75f3dbfe24c208a8", + "address": "0x3ce6649a9c682a6e0e7c4bcf9768046fd8f3cd109dfe401a3e9fcb699c209db", "class_hash": "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33", "original_class_hash": "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", @@ -1641,7 +1673,7 @@ }, { "kind": "DojoContract", - "address": "0x44e1b43ee34f816374612ae2df4a668e76a1aa723de8d7b67166e10a7225112", + "address": "0x4a205ce2f721fa431fc3aa378de3f60cbcdf6e8f7d5a93b1d6f3e9f0d4e46cf", "class_hash": "0x14b3096b82a761f63dd47277c2b5ac18925dea43586418483939a2f1f57f674", "original_class_hash": "0x14b3096b82a761f63dd47277c2b5ac18925dea43586418483939a2f1f57f674", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", @@ -1878,7 +1910,7 @@ }, { "kind": "DojoContract", - "address": "0x6840cf5bebab9c134ddc4d34f6b021684610d7b83d663fc46e2e10d3569ea15", + "address": "0x429eb42bade972a3d14c5742afe26fccf75c58cef2c7f24d44efa79d32a0657", "class_hash": "0x761d18a3557d98b3962ebb2c9ddae89ad586ce81de7e86c5fd1e1b4f9d0028", "original_class_hash": "0x761d18a3557d98b3962ebb2c9ddae89ad586ce81de7e86c5fd1e1b4f9d0028", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", @@ -2097,7 +2129,7 @@ }, { "kind": "DojoContract", - "address": "0x512bcb4058b044f689269d8a1c23e653c04baee2029f7e5d3f4ec053e6c5c91", + "address": "0x3e6653e00f28a256d6745d3057bc36e9e0bb283998eda778ae558c97c14a7d2", "class_hash": "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7", "original_class_hash": "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml index f6bacb4b73..fbf09eb3dc 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml @@ -1,10 +1,10 @@ [world] kind = "WorldContract" -class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" -original_class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" +class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" +original_class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" abi = "manifests/dev/deployment/abis/dojo-world.json" -address = "0x5377ecb8b7b6ce3f17daf9064a5f5ee7f6642c3e72579b45478a828007db355" -transaction_hash = "0x59c745b80871acdab7ad1c29703cac9aa949f4326b32037943512adc0a19ab2" +address = "0x36d0f2bb88ec90b2eb4b3ae2dae98372c5c27fead89fb6cf4d5a43231e90d2f" +transaction_hash = "0x2a49aacf9d50af1268a841c07cc6e014825a2be95f89d5ce8e61fc2895cce9d" block_number = 3 seed = "dojo_examples" manifest_name = "dojo-world" @@ -23,7 +23,7 @@ manifest_name = "dojo-base" [[contracts]] kind = "DojoContract" -address = "0x5c92c8995272a6ae073392c6878fe80cd71ae0be4931bce75f3dbfe24c208a8" +address = "0x3ce6649a9c682a6e0e7c4bcf9768046fd8f3cd109dfe401a3e9fcb699c209db" class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" original_class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" @@ -40,7 +40,7 @@ manifest_name = "dojo_examples-actions-40b6994c" [[contracts]] kind = "DojoContract" -address = "0x44e1b43ee34f816374612ae2df4a668e76a1aa723de8d7b67166e10a7225112" +address = "0x4a205ce2f721fa431fc3aa378de3f60cbcdf6e8f7d5a93b1d6f3e9f0d4e46cf" class_hash = "0x14b3096b82a761f63dd47277c2b5ac18925dea43586418483939a2f1f57f674" original_class_hash = "0x14b3096b82a761f63dd47277c2b5ac18925dea43586418483939a2f1f57f674" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" @@ -54,7 +54,7 @@ manifest_name = "dojo_examples-dungeon-6620e0e6" [[contracts]] kind = "DojoContract" -address = "0x6840cf5bebab9c134ddc4d34f6b021684610d7b83d663fc46e2e10d3569ea15" +address = "0x429eb42bade972a3d14c5742afe26fccf75c58cef2c7f24d44efa79d32a0657" class_hash = "0x761d18a3557d98b3962ebb2c9ddae89ad586ce81de7e86c5fd1e1b4f9d0028" original_class_hash = "0x761d18a3557d98b3962ebb2c9ddae89ad586ce81de7e86c5fd1e1b4f9d0028" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" @@ -68,7 +68,7 @@ manifest_name = "dojo_examples-mock_token-31599eb2" [[contracts]] kind = "DojoContract" -address = "0x512bcb4058b044f689269d8a1c23e653c04baee2029f7e5d3f4ec053e6c5c91" +address = "0x3e6653e00f28a256d6745d3057bc36e9e0bb283998eda778ae558c97c14a7d2" class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" original_class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" diff --git a/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json b/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json index fe02b53f14..48a015a203 100644 --- a/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world::StoreDelRecord", @@ -1156,6 +1183,11 @@ "type": "dojo::world::world::StoreUpdateRecord", "kind": "nested" }, + { + "name": "StoreUpdateMember", + "type": "dojo::world::world::StoreUpdateMember", + "kind": "nested" + }, { "name": "StoreDelRecord", "type": "dojo::world::world::StoreDelRecord", diff --git a/examples/spawn-and-move/manifests/release/base/dojo-world.toml b/examples/spawn-and-move/manifests/release/base/dojo-world.toml index 5891e40ff4..5072a82b86 100644 --- a/examples/spawn-and-move/manifests/release/base/dojo-world.toml +++ b/examples/spawn-and-move/manifests/release/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" -original_class_hash = "0x26a8f65e0b0ba2a6d2f9e93d4f72f75eabebb853ea7413e134b3902ea352557" +class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" +original_class_hash = "0x7c5960ecfee50226cf08560851f996d91627a8893e9376613624c61838fb820" abi = "manifests/release/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" From 934324990f112c4864086e5c93b74db414077c74 Mon Sep 17 00:00:00 2001 From: glihm Date: Thu, 18 Jul 2024 08:58:17 -0600 Subject: [PATCH 10/35] fix: ensure event messages are emitted with the correct selector --- crates/dojo-lang/src/event.rs | 3 ++- .../base/contracts/dojo_examples-actions-40b6994c.toml | 4 ++-- .../dev/base/contracts/dojo_examples-others-61de2c18.toml | 4 ++-- .../spawn-and-move/manifests/dev/deployment/manifest.json | 8 ++++---- .../spawn-and-move/manifests/dev/deployment/manifest.toml | 8 ++++---- .../base/contracts/dojo_examples-actions-40b6994c.toml | 4 ++-- .../base/contracts/dojo_examples-others-61de2c18.toml | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/crates/dojo-lang/src/event.rs b/crates/dojo-lang/src/event.rs index 455e76e19b..4058d93759 100644 --- a/crates/dojo-lang/src/event.rs +++ b/crates/dojo-lang/src/event.rs @@ -82,7 +82,8 @@ pub fn handle_event_struct( fn append_keys_and_data( self: @$struct_name$, ref keys: Array, ref data: Array ) {{ - core::array::ArrayTrait::append(ref keys, selector!(\"$struct_name$\")); + core::array::ArrayTrait::append(ref keys, \ + dojo::model::Model::<$struct_name$>::selector()); $append_members$ }} fn deserialize( diff --git a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml index fb28175143..d8e6eb4353 100644 --- a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml +++ b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" -original_class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" +class_hash = "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01" +original_class_hash = "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] diff --git a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml index 70a3bb5255..af23bfa1ec 100644 --- a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml +++ b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-others-61de2c18.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" -original_class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" +class_hash = "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4" +original_class_hash = "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/dojo_examples-others-61de2c18.json" reads = [] diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.json b/examples/spawn-and-move/manifests/dev/deployment/manifest.json index f456a3cc3e..b7109e0f63 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.json +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.json @@ -1243,8 +1243,8 @@ { "kind": "DojoContract", "address": "0x3ce6649a9c682a6e0e7c4bcf9768046fd8f3cd109dfe401a3e9fcb699c209db", - "class_hash": "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33", - "original_class_hash": "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33", + "class_hash": "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01", + "original_class_hash": "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", "abi": [ { @@ -2130,8 +2130,8 @@ { "kind": "DojoContract", "address": "0x3e6653e00f28a256d6745d3057bc36e9e0bb283998eda778ae558c97c14a7d2", - "class_hash": "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7", - "original_class_hash": "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7", + "class_hash": "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4", + "original_class_hash": "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4", "base_class_hash": "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4", "abi": [ { diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml index fbf09eb3dc..ddc1f3138d 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml @@ -24,8 +24,8 @@ manifest_name = "dojo-base" [[contracts]] kind = "DojoContract" address = "0x3ce6649a9c682a6e0e7c4bcf9768046fd8f3cd109dfe401a3e9fcb699c209db" -class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" -original_class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" +class_hash = "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01" +original_class_hash = "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" abi = "manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] @@ -69,8 +69,8 @@ manifest_name = "dojo_examples-mock_token-31599eb2" [[contracts]] kind = "DojoContract" address = "0x3e6653e00f28a256d6745d3057bc36e9e0bb283998eda778ae558c97c14a7d2" -class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" -original_class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" +class_hash = "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4" +original_class_hash = "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4" base_class_hash = "0x26a4f5d2d9638877a2648297339275df5eaab0adb3cdf0010887c2dbf2be4" abi = "manifests/dev/deployment/abis/contracts/dojo_examples-others-61de2c18.json" reads = [] diff --git a/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml b/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml index 445640874c..e93e70607f 100644 --- a/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml +++ b/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" -original_class_hash = "0x676eed1c5c6c5f1ddf488914d137e07761d1a320df8a50fbf75ecf209624a33" +class_hash = "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01" +original_class_hash = "0x7b59e8f1039dd99e39af7695bbbd5bcc4ffd7852f54576fe4acf89590298c01" base_class_hash = "0x0" abi = "manifests/release/base/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] diff --git a/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml b/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml index eb147736c9..24758c22e0 100644 --- a/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml +++ b/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-others-61de2c18.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" -original_class_hash = "0x479bfb12dcba5398d77303e7a665fc3fedb16f2d7f9cb1f5d7e2beb3b7e2ba7" +class_hash = "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4" +original_class_hash = "0x112caad1aed1e3d21fc70eb118db9ff75632f1e3f6c2f387d116fcb6e1eee4" base_class_hash = "0x0" abi = "manifests/release/base/abis/contracts/dojo_examples-others-61de2c18.json" reads = [] From acf7c60e38b5f986be3666441d452169987de8ea Mon Sep 17 00:00:00 2001 From: glihm Date: Thu, 18 Jul 2024 10:08:57 -0600 Subject: [PATCH 11/35] fix: cairo fmt --- crates/dojo-core/src/world.cairo | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/dojo-core/src/world.cairo b/crates/dojo-core/src/world.cairo index 9b4048f3b8..a230fd9b6c 100644 --- a/crates/dojo-core/src/world.cairo +++ b/crates/dojo-core/src/world.cairo @@ -851,9 +851,15 @@ pub mod world { ModelIndex::MemberId(( entity_id, member_selector )) => { - self._write_model_member(model_selector, entity_id, member_selector, values, layout); + self + ._write_model_member( + model_selector, entity_id, member_selector, values, layout + ); EventEmitter::emit( - ref self, StoreUpdateMember { table: model_selector, entity_id, member_selector, values } + ref self, + StoreUpdateMember { + table: model_selector, entity_id, member_selector, values + } ); } } From 8bcaf36559e22fb42acc48a4dae0680bc2ab7c9c Mon Sep 17 00:00:00 2001 From: glihm Date: Thu, 18 Jul 2024 10:53:59 -0600 Subject: [PATCH 12/35] fix: fix test typo --- crates/sozo/ops/src/events.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sozo/ops/src/events.rs b/crates/sozo/ops/src/events.rs index cd182b3df7..8c4703021c 100644 --- a/crates/sozo/ops/src/events.rs +++ b/crates/sozo/ops/src/events.rs @@ -279,7 +279,7 @@ mod tests { let result = extract_events(&manifest, &project_dir, &target_dir).unwrap(); // we are just collecting all events from manifest file so just verifying count should work - assert_eq!(result.len(), 17); + assert_eq!(result.len(), 18); } #[test] From 91949d5e71a08a54d8f20e22355dc9401f6c2ea6 Mon Sep 17 00:00:00 2001 From: glihm Date: Thu, 18 Jul 2024 16:29:40 -0600 Subject: [PATCH 13/35] wip: --- Cargo.toml | 2 +- .../src/processors/store_update_member.rs | 28 ++++++++++++------- crates/torii/core/src/sql.rs | 15 +++++----- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 74569d2263..cf28f3c838 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,7 +236,7 @@ alloy-provider = { version = "0.2", default-features = false, features = [ ] } alloy-rpc-types-eth = { version = "0.2", default-features = false } alloy-signer = { version = "0.2", default-features = false } -alloy-transport = { version = "0.2" } +alloy-transport = { version = "0.2", default-features = false } [patch.crates-io] cairo-felt = { git = "https://github.com/dojoengine/cairo-rs.git", rev = "1031381" } diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 73a6752aff..635d2815b8 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -7,7 +7,7 @@ use num_traits::ToPrimitive; use starknet::core::types::{Event, TransactionReceiptWithBlockInfo}; use starknet::core::utils::get_selector_from_name; use starknet::providers::Provider; -use tracing::info; +use tracing::{info, warn}; use super::EventProcessor; use crate::processors::{ENTITY_ID_INDEX, MODEL_INDEX}; @@ -58,7 +58,8 @@ where let model = db.model(selector).await?; let schema = model.schema().await?; - let mut ty = schema + + let member = schema .as_struct() .expect("model schema must be a struct") .children @@ -68,14 +69,13 @@ where == member_selector }) .context("member not found")? - .ty .clone(); info!( target: LOG_TARGET, name = %model.name(), entity_id = format!("{:#x}", entity_id), - member = %ty.name(), + member = %member.name, "Store update member.", ); @@ -84,16 +84,24 @@ where values_start + event.data[values_start].to_usize().context("invalid usize")?; // Skip the length to only get the values as they will be deserialized. - let values = event.data[values_start + 1..=values_end].to_vec(); + let mut values = event.data[values_start + 1..=values_end].to_vec(); let tag = naming::get_tag(model.namespace(), model.name()); - // Keys are read from the db, since we don't have access to them when only - // the entity id is passed. - let keys = db.get_entity_keys(entity_id, &tag).await?; - let mut keys_and_unpacked = [keys, values].concat(); + if !db.does_entity_exist(tag.clone(), entity_id).await? { + warn!( + target: LOG_TARGET, + tag, + entity_id = format!("{:#x}", entity_id), + "Entity not found, must be set before updating a member.", + ); + + return Ok(()); + } + + let mut ty = member.ty.clone(); + ty.deserialize(&mut values)?; - ty.deserialize(&mut keys_and_unpacked)?; db.set_model_member(entity_id, false, &schema.name(), &ty, event_id, block_timestamp).await } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 339b5f2f41..8276bcd414 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -283,7 +283,7 @@ impl Sql { block_timestamp: u64, ) -> Result<()> { let entity_id = format!("{:#x}", entity_id); - let path = vec![model_tag.to_string()]; + let path = vec![model_tag.to_string(), member.name()]; // update model member self.build_set_entity_queries_recursive( path, @@ -410,14 +410,13 @@ impl Sql { Ok(keys) } - pub async fn entity(&self, model: String, key: Felt) -> Result> { - let query = sqlx::query_as::<_, (i32, String, String)>("SELECT * FROM ? WHERE id = ?") - .bind(model) - .bind(format!("{:#x}", key)); + pub async fn does_entity_exist(&self, model: String, key: Felt) -> Result { + let sql = format!("SELECT COUNT(*) FROM [{model}] WHERE id = ?"); - let mut conn: PoolConnection = self.pool.acquire().await?; - let row: (i32, String, String) = query.fetch_one(&mut *conn).await?; - Ok(serde_json::from_str(&row.2).unwrap()) + let count: i64 = + sqlx::query_scalar(&sql).bind(format!("{:#x}", key)).fetch_one(&self.pool).await?; + + Ok(count > 0) } pub async fn entities(&self, model: String) -> Result>> { From 7fa5f5a8b193cab1d2cc0076667d2066fa14f750 Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 00:46:57 +0100 Subject: [PATCH 14/35] fix: simple types model memebr update --- crates/torii/core/src/sql.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 8276bcd414..a788f6cc01 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use chrono::Utc; use dojo_types::primitive::Primitive; -use dojo_types::schema::{EnumOption, Member, Ty}; +use dojo_types::schema::{EnumOption, Member, Struct, Ty}; use dojo_world::contracts::abi::model::Layout; use dojo_world::contracts::naming::compute_selector_from_names; use dojo_world::metadata::WorldMetadata; @@ -283,13 +283,19 @@ impl Sql { block_timestamp: u64, ) -> Result<()> { let entity_id = format!("{:#x}", entity_id); - let path = vec![model_tag.to_string(), member.name()]; + let path = vec![model_tag.to_string()]; + + let wrapped_ty = Ty::Struct(Struct { + name: model_tag.to_string(), + children: vec![Member { name: member.name(), ty: member.clone(), key: false }], + }); + // update model member self.build_set_entity_queries_recursive( path, event_id, (&entity_id, is_event_message), - member, + &wrapped_ty, block_timestamp, &vec![], ); @@ -684,7 +690,11 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } + if let Ty::Tuple(t) = &o.ty { + t.is_empty() + } else { + false + } }, ) { return; From 8d14285c7720611627c4e22f8793aa843695f92b Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 00:49:32 +0100 Subject: [PATCH 15/35] chore; pass memmber type to func --- crates/torii/core/src/processors/store_update_member.rs | 3 +-- crates/torii/core/src/sql.rs | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 635d2815b8..0fe54ed56f 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -99,8 +99,7 @@ where return Ok(()); } - let mut ty = member.ty.clone(); - ty.deserialize(&mut values)?; + member.ty.deserialize(&mut values)?; db.set_model_member(entity_id, false, &schema.name(), &ty, event_id, block_timestamp).await } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index a788f6cc01..998e42bb41 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -278,17 +278,15 @@ impl Sql { entity_id: Felt, is_event_message: bool, model_tag: &str, - member: &Ty, + member: &Member, event_id: &str, block_timestamp: u64, ) -> Result<()> { let entity_id = format!("{:#x}", entity_id); let path = vec![model_tag.to_string()]; - let wrapped_ty = Ty::Struct(Struct { - name: model_tag.to_string(), - children: vec![Member { name: member.name(), ty: member.clone(), key: false }], - }); + let wrapped_ty = + Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); // update model member self.build_set_entity_queries_recursive( From 7e4c56c3e4a9e49cfa0ea6a490969128c268c09e Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 00:56:34 +0100 Subject: [PATCH 16/35] chore: clean code --- .../src/processors/store_update_member.rs | 10 ++++-- crates/torii/core/src/sql.rs | 31 +------------------ 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 0fe54ed56f..bb18e1aff8 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Error, Result}; use async_trait::async_trait; +use dojo_types::schema::{Struct, Ty}; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::naming; use dojo_world::contracts::world::WorldContractReader; @@ -59,7 +60,7 @@ where let model = db.model(selector).await?; let schema = model.schema().await?; - let member = schema + let mut member = schema .as_struct() .expect("model schema must be a struct") .children @@ -101,6 +102,11 @@ where member.ty.deserialize(&mut values)?; - db.set_model_member(entity_id, false, &schema.name(), &ty, event_id, block_timestamp).await + db.set_entity( + Ty::Struct(Struct { name: schema.name(), children: vec![member.clone()] }), + event_id, + block_timestamp, + ) + .await } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 998e42bb41..8647797bb2 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use chrono::Utc; use dojo_types::primitive::Primitive; -use dojo_types::schema::{EnumOption, Member, Struct, Ty}; +use dojo_types::schema::{EnumOption, Member, Ty}; use dojo_world::contracts::abi::model::Layout; use dojo_world::contracts::naming::compute_selector_from_names; use dojo_world::metadata::WorldMetadata; @@ -273,35 +273,6 @@ impl Sql { Ok(()) } - pub async fn set_model_member( - &mut self, - entity_id: Felt, - is_event_message: bool, - model_tag: &str, - member: &Member, - event_id: &str, - block_timestamp: u64, - ) -> Result<()> { - let entity_id = format!("{:#x}", entity_id); - let path = vec![model_tag.to_string()]; - - let wrapped_ty = - Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); - - // update model member - self.build_set_entity_queries_recursive( - path, - event_id, - (&entity_id, is_event_message), - &wrapped_ty, - block_timestamp, - &vec![], - ); - self.query_queue.execute_all().await?; - - Ok(()) - } - pub async fn delete_entity(&mut self, entity_id: Felt, entity: Ty) -> Result<()> { let entity_id = format!("{:#x}", entity_id); let path = vec![entity.name()]; From 6f23b9a092ed727f7de28517292f9398d2dc6318 Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 00:57:28 +0100 Subject: [PATCH 17/35] fmt --- crates/torii/core/src/sql.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 8647797bb2..123083b4fc 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -659,11 +659,7 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { - t.is_empty() - } else { - false - } + if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } }, ) { return; From 59736eecd3a1359e90ee13c21638c886bbec844b Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 01:04:41 +0100 Subject: [PATCH 18/35] wip --- .../src/processors/store_update_member.rs | 8 ++-- crates/torii/core/src/sql.rs | 37 ++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index bb18e1aff8..249b1aa5c6 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -1,6 +1,5 @@ use anyhow::{Context, Error, Result}; use async_trait::async_trait; -use dojo_types::schema::{Struct, Ty}; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::naming; use dojo_world::contracts::world::WorldContractReader; @@ -102,8 +101,11 @@ where member.ty.deserialize(&mut values)?; - db.set_entity( - Ty::Struct(Struct { name: schema.name(), children: vec![member.clone()] }), + db.set_model_member( + entity_id, + false, + &schema.name(), + &member, event_id, block_timestamp, ) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 123083b4fc..998e42bb41 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use chrono::Utc; use dojo_types::primitive::Primitive; -use dojo_types::schema::{EnumOption, Member, Ty}; +use dojo_types::schema::{EnumOption, Member, Struct, Ty}; use dojo_world::contracts::abi::model::Layout; use dojo_world::contracts::naming::compute_selector_from_names; use dojo_world::metadata::WorldMetadata; @@ -273,6 +273,35 @@ impl Sql { Ok(()) } + pub async fn set_model_member( + &mut self, + entity_id: Felt, + is_event_message: bool, + model_tag: &str, + member: &Member, + event_id: &str, + block_timestamp: u64, + ) -> Result<()> { + let entity_id = format!("{:#x}", entity_id); + let path = vec![model_tag.to_string()]; + + let wrapped_ty = + Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); + + // update model member + self.build_set_entity_queries_recursive( + path, + event_id, + (&entity_id, is_event_message), + &wrapped_ty, + block_timestamp, + &vec![], + ); + self.query_queue.execute_all().await?; + + Ok(()) + } + pub async fn delete_entity(&mut self, entity_id: Felt, entity: Ty) -> Result<()> { let entity_id = format!("{:#x}", entity_id); let path = vec![entity.name()]; @@ -659,7 +688,11 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } + if let Ty::Tuple(t) = &o.ty { + t.is_empty() + } else { + false + } }, ) { return; From 98b7d4862d0cc0e25dde0e006ae176c6b6c20c22 Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 01:20:59 +0100 Subject: [PATCH 19/35] fix: upsert to avoid constraint CHECK failing --- crates/torii/core/src/sql.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 998e42bb41..4e0cae0e0e 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -660,9 +660,12 @@ impl Sql { let placeholders: Vec<&str> = arguments.iter().map(|_| "?").collect(); let statement = format!( - "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({})", + // on conflict do update to set all of the columns to the new values + "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({}) ON CONFLICT(id) DO UPDATE SET {}", columns.join(","), - placeholders.join(",") + placeholders.join(","), + // exclude the first column (id) from the update + columns.iter().skip(1).map(|c| format!("{} = EXCLUDED.{}", c, c)).collect::>().join(", ") ); query_queue.enqueue(statement, arguments); From 5d8e1419c65153c8453822021685bc813b91d273 Mon Sep 17 00:00:00 2001 From: Nasr Date: Fri, 19 Jul 2024 01:21:32 +0100 Subject: [PATCH 20/35] fmt --- bin/sozo/src/commands/mod.rs | 4 ++-- crates/katana/storage/provider/src/error.rs | 4 +++- .../core/src/processors/store_update_member.rs | 11 ++--------- crates/torii/core/src/sql.rs | 16 +++++++++------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/bin/sozo/src/commands/mod.rs b/bin/sozo/src/commands/mod.rs index 788d0b8fe2..158fd8bfed 100644 --- a/bin/sozo/src/commands/mod.rs +++ b/bin/sozo/src/commands/mod.rs @@ -53,8 +53,8 @@ pub enum Commands { Init(InitArgs), #[command(about = "Remove generated artifacts, manifests and abis")] Clean(CleanArgs), - #[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), #[command(about = "Developer mode: watcher for building and migration")] Dev(DevArgs), diff --git a/crates/katana/storage/provider/src/error.rs b/crates/katana/storage/provider/src/error.rs index 3876bbeec7..c02fda220d 100644 --- a/crates/katana/storage/provider/src/error.rs +++ b/crates/katana/storage/provider/src/error.rs @@ -73,7 +73,9 @@ pub enum ProviderError { /// Error when a contract nonce change entry is not found but the block number of when the /// change happen exists in the nonce change list. - #[error("Missing contract nonce change entry for contract {contract_address} at block {block}")] + #[error( + "Missing contract nonce change entry for contract {contract_address} at block {block}" + )] MissingContractNonceChangeEntry { /// The block number of when the change happen. block: BlockNumber, diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 249b1aa5c6..f8125757db 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -101,14 +101,7 @@ where member.ty.deserialize(&mut values)?; - db.set_model_member( - entity_id, - false, - &schema.name(), - &member, - event_id, - block_timestamp, - ) - .await + db.set_model_member(entity_id, false, &schema.name(), &member, event_id, block_timestamp) + .await } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 4e0cae0e0e..be0ed8e967 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -661,11 +661,17 @@ impl Sql { let placeholders: Vec<&str> = arguments.iter().map(|_| "?").collect(); let statement = format!( // on conflict do update to set all of the columns to the new values - "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({}) ON CONFLICT(id) DO UPDATE SET {}", + "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({}) ON CONFLICT(id) DO \ + UPDATE SET {}", columns.join(","), placeholders.join(","), // exclude the first column (id) from the update - columns.iter().skip(1).map(|c| format!("{} = EXCLUDED.{}", c, c)).collect::>().join(", ") + columns + .iter() + .skip(1) + .map(|c| format!("{} = EXCLUDED.{}", c, c)) + .collect::>() + .join(", ") ); query_queue.enqueue(statement, arguments); @@ -691,11 +697,7 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { - t.is_empty() - } else { - false - } + if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } }, ) { return; From 2e87cde59abe96124727b8a44294a96f23a151ed Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 29 Jul 2024 15:55:36 +0200 Subject: [PATCH 21/35] fix: figure out way to fix upsert issue to reuse func --- .../src/processors/store_update_member.rs | 7 +-- crates/torii/core/src/sql.rs | 56 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index f8125757db..ae52d438d9 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -68,8 +68,7 @@ where get_selector_from_name(&c.name).expect("invalid selector for member name") == member_selector }) - .context("member not found")? - .clone(); + .context("member not found")?; info!( target: LOG_TARGET, @@ -101,7 +100,7 @@ where member.ty.deserialize(&mut values)?; - db.set_model_member(entity_id, false, &schema.name(), &member, event_id, block_timestamp) - .await + db.set_entity(schema, event_id, block_timestamp).await?; + Ok(()) } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index be0ed8e967..98d4e04049 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -273,34 +273,34 @@ impl Sql { Ok(()) } - pub async fn set_model_member( - &mut self, - entity_id: Felt, - is_event_message: bool, - model_tag: &str, - member: &Member, - event_id: &str, - block_timestamp: u64, - ) -> Result<()> { - let entity_id = format!("{:#x}", entity_id); - let path = vec![model_tag.to_string()]; - - let wrapped_ty = - Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); - - // update model member - self.build_set_entity_queries_recursive( - path, - event_id, - (&entity_id, is_event_message), - &wrapped_ty, - block_timestamp, - &vec![], - ); - self.query_queue.execute_all().await?; - - Ok(()) - } + // pub async fn set_model_member( + // &mut self, + // entity_id: Felt, + // is_event_message: bool, + // model_tag: &str, + // member: &Member, + // event_id: &str, + // block_timestamp: u64, + // ) -> Result<()> { + // let entity_id = format!("{:#x}", entity_id); + // let path = vec![model_tag.to_string()]; + + // let wrapped_ty = + // Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); + + // // update model member + // self.build_set_entity_queries_recursive( + // path, + // event_id, + // (&entity_id, is_event_message), + // &wrapped_ty, + // block_timestamp, + // &vec![], + // ); + // self.query_queue.execute_all().await?; + + // Ok(()) + // } pub async fn delete_entity(&mut self, entity_id: Felt, entity: Ty) -> Result<()> { let entity_id = format!("{:#x}", entity_id); From ddb37c3167cdf591d1c98c65768630446fe7b272 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 29 Jul 2024 16:19:21 +0200 Subject: [PATCH 22/35] refactor: refactor recursive set to handle store update member --- crates/torii/core/src/sql.rs | 101 +++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 98d4e04049..859f15f373 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -24,6 +24,7 @@ use crate::types::{ use crate::utils::{must_utc_datetime_from_timestamp, utc_dt_string_from_timestamp}; type IsEventMessage = bool; +type IsStoreUpdateMember = bool; pub const FELT_DELIMITER: &str = "/"; @@ -203,7 +204,7 @@ impl Sql { path, event_id, (&entity_id, false), - &entity, + (&entity, false), block_timestamp, &vec![], ); @@ -262,7 +263,7 @@ impl Sql { path, event_id, (&entity_id, true), - &entity, + (&entity, false), block_timestamp, &vec![], ); @@ -273,34 +274,30 @@ impl Sql { Ok(()) } - // pub async fn set_model_member( - // &mut self, - // entity_id: Felt, - // is_event_message: bool, - // model_tag: &str, - // member: &Member, - // event_id: &str, - // block_timestamp: u64, - // ) -> Result<()> { - // let entity_id = format!("{:#x}", entity_id); - // let path = vec![model_tag.to_string()]; - - // let wrapped_ty = - // Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); - - // // update model member - // self.build_set_entity_queries_recursive( - // path, - // event_id, - // (&entity_id, is_event_message), - // &wrapped_ty, - // block_timestamp, - // &vec![], - // ); - // self.query_queue.execute_all().await?; - - // Ok(()) - // } + pub async fn set_model_member( + &mut self, + entity_id: Felt, + is_event_message: bool, + entity: &Ty, + event_id: &str, + block_timestamp: u64, + ) -> Result<()> { + let entity_id = format!("{:#x}", entity_id); + let path = vec![entity.name()]; + + // update model member + self.build_set_entity_queries_recursive( + path, + event_id, + (&entity_id, is_event_message), + (&wrapped_ty, true), + block_timestamp, + &vec![], + ); + self.query_queue.execute_all().await?; + + Ok(()) + } pub async fn delete_entity(&mut self, entity_id: Felt, entity: Ty) -> Result<()> { let entity_id = format!("{:#x}", entity_id); @@ -592,11 +589,12 @@ impl Sql { event_id: &str, // The id of the entity and if the entity is an event message entity_id: (&str, IsEventMessage), - entity: &Ty, + entity: (&Ty, IsStoreUpdateMember), block_timestamp: u64, indexes: &Vec, ) { let (entity_id, is_event_message) = entity_id; + let (entity, is_store_update_member) = entity; let update_members = |members: &[Member], query_queue: &mut QueryQueue, indexes: &Vec| { @@ -659,20 +657,27 @@ impl Sql { } let placeholders: Vec<&str> = arguments.iter().map(|_| "?").collect(); - let statement = format!( - // on conflict do update to set all of the columns to the new values - "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({}) ON CONFLICT(id) DO \ - UPDATE SET {}", - columns.join(","), - placeholders.join(","), - // exclude the first column (id) from the update - columns - .iter() - .skip(1) - .map(|c| format!("{} = EXCLUDED.{}", c, c)) - .collect::>() - .join(", ") - ); + let statement = if is_store_update_member { + // row has to exist. update it directly + format!( + "UPDATE [{table_id}] SET {updates} WHERE entity_id = ?", + table_id = table_id, + updates = columns + .iter() + // skip id column + .skip(1) + .zip(placeholders.iter().skip(1)) + .map(|(column, placeholder)| format!("{} = {}", column, placeholder)) + .collect::>() + .join(", ") + ) + } else { + format!( + "INSERT OR REPLACE INTO [{table_id}] ({}) VALUES ({})", + columns.join(","), + placeholders.join(",") + ) + }; query_queue.enqueue(statement, arguments); }; @@ -697,7 +702,11 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } + if let Ty::Tuple(t) = &o.ty { + t.is_empty() + } else { + false + } }, ) { return; From ac41ee0aa9b96688ab31570dedc898846d23f01c Mon Sep 17 00:00:00 2001 From: glihm Date: Mon, 29 Jul 2024 22:44:51 -0600 Subject: [PATCH 23/35] fix: fix world typo and merge --- .../dojo-core/src/world/world_contract.cairo | 3 +- .../manifests/dev/base/abis/dojo-world.json | 29 +++++++++++- .../manifests/dev/base/dojo-world.toml | 4 +- crates/dojo-world/src/contracts/abi/world.rs | 29 +++++++++++- examples/spawn-and-move/Scarb.toml | 2 +- .../manifests/dev/base/abis/dojo-world.json | 29 +++++++++++- .../manifests/dev/base/dojo-world.toml | 4 +- .../dev/deployment/abis/dojo-world.json | 29 +++++++++++- .../manifests/dev/deployment/manifest.json | 45 +++++++++++++++---- .../manifests/dev/deployment/manifest.toml | 16 +++---- .../release/base/abis/dojo-world.json | 29 +++++++++++- .../manifests/release/base/dojo-world.toml | 4 +- 12 files changed, 192 insertions(+), 31 deletions(-) diff --git a/crates/dojo-core/src/world/world_contract.cairo b/crates/dojo-core/src/world/world_contract.cairo index eea4f72a4f..732b177cf8 100644 --- a/crates/dojo-core/src/world/world_contract.cairo +++ b/crates/dojo-core/src/world/world_contract.cairo @@ -832,8 +832,7 @@ pub mod world { ModelIndex::MemberId(( entity_id, member_selector )) => { - self.write_model_member(model_selector, entity_id, member_id, values, layout); - // TODO: here we need a new event update and see how Torii can process that. + self.write_model_member(model_selector, entity_id, member_selector, values, layout); EventEmitter::emit( ref self, StoreUpdateMember { diff --git a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json index dbec675bc2..c5f374f4e0 100644 --- a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json +++ b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world_contract::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world_contract::world::StoreDelRecord", @@ -1158,7 +1185,7 @@ }, { "name": "StoreUpdateMember", - "type": "dojo::world::world::StoreUpdateMember", + "type": "dojo::world::world_contract::world::StoreUpdateMember", "kind": "nested" }, { diff --git a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml index 612934eb2e..1bfe243487 100644 --- a/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml +++ b/crates/dojo-lang/src/manifest_test_data/compiler_cairo/manifests/dev/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" -original_class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" +class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" +original_class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" abi = "manifests/dev/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" diff --git a/crates/dojo-world/src/contracts/abi/world.rs b/crates/dojo-world/src/contracts/abi/world.rs index d5e64ad3db..a2ad16d47b 100644 --- a/crates/dojo-world/src/contracts/abi/world.rs +++ b/crates/dojo-world/src/contracts/abi/world.rs @@ -981,6 +981,33 @@ abigen!( } ] }, + { + "type": "event", + "name": "dojo::world::world_contract::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world_contract::world::StoreDelRecord", @@ -1164,7 +1191,7 @@ abigen!( }, { "name": "StoreUpdateMember", - "type": "dojo::world::world::StoreUpdateMember", + "type": "dojo::world::world_contract::world::StoreUpdateMember", "kind": "nested" }, { diff --git a/examples/spawn-and-move/Scarb.toml b/examples/spawn-and-move/Scarb.toml index 61945087e5..0de9c0f1f3 100644 --- a/examples/spawn-and-move/Scarb.toml +++ b/examples/spawn-and-move/Scarb.toml @@ -43,7 +43,7 @@ rpc_url = "http://localhost:5050/" # Default account for katana with seed = 0 account_address = "0x6162896d1d7ab204c7ccac6dd5f8e9e7c25ecd5ae4fcb4ad32e57786bb46e03" private_key = "0x1800000000300000180000000000030000000000003006001800006600" -world_address = "0x64525f120f0c0bfaa610e38fad3ace40ff8c696e0c498697d73e0f58fd5ad1" +world_address = "0xb91ef4f63e433b419ec4ec3647676f9c84d06bbcb16ff153fd911e6cb77f73" [profile.release.tool.dojo] # for more info on how `merge-strategy` works see: diff --git a/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json b/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json index dbec675bc2..c5f374f4e0 100644 --- a/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/dev/base/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world_contract::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world_contract::world::StoreDelRecord", @@ -1158,7 +1185,7 @@ }, { "name": "StoreUpdateMember", - "type": "dojo::world::world::StoreUpdateMember", + "type": "dojo::world::world_contract::world::StoreUpdateMember", "kind": "nested" }, { diff --git a/examples/spawn-and-move/manifests/dev/base/dojo-world.toml b/examples/spawn-and-move/manifests/dev/base/dojo-world.toml index 612934eb2e..1bfe243487 100644 --- a/examples/spawn-and-move/manifests/dev/base/dojo-world.toml +++ b/examples/spawn-and-move/manifests/dev/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" -original_class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" +class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" +original_class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" abi = "manifests/dev/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" diff --git a/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json b/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json index dbec675bc2..c5f374f4e0 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/dev/deployment/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world_contract::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world_contract::world::StoreDelRecord", @@ -1158,7 +1185,7 @@ }, { "name": "StoreUpdateMember", - "type": "dojo::world::world::StoreUpdateMember", + "type": "dojo::world::world_contract::world::StoreUpdateMember", "kind": "nested" }, { diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.json b/examples/spawn-and-move/manifests/dev/deployment/manifest.json index ad2be64dc8..d1db654f97 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.json +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.json @@ -1,8 +1,8 @@ { "world": { "kind": "WorldContract", - "class_hash": "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde", - "original_class_hash": "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde", + "class_hash": "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7", + "original_class_hash": "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7", "abi": [ { "type": "impl", @@ -980,6 +980,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world_contract::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world_contract::world::StoreDelRecord", @@ -1163,7 +1190,7 @@ }, { "name": "StoreUpdateMember", - "type": "dojo::world::world::StoreUpdateMember", + "type": "dojo::world::world_contract::world::StoreUpdateMember", "kind": "nested" }, { @@ -1194,8 +1221,8 @@ ] } ], - "address": "0x64525f120f0c0bfaa610e38fad3ace40ff8c696e0c498697d73e0f58fd5ad1", - "transaction_hash": "0x1a996413193677077362ecedda60227f345b0bb1b5c173b9a82f5cb8b584e8b", + "address": "0xb91ef4f63e433b419ec4ec3647676f9c84d06bbcb16ff153fd911e6cb77f73", + "transaction_hash": "0x6e759f50f367f4de947b3695d871db5584548c2f206ce49810f626b5fdbca9", "block_number": 3, "seed": "dojo_examples", "metadata": { @@ -1215,7 +1242,7 @@ "contracts": [ { "kind": "DojoContract", - "address": "0x668a24b0352dec79bd4661685fe1b152f33989bd3dc2dbdb094491fb1bdd589", + "address": "0x653b7e7bdc1596674dd81b7e4a61e859f9852d171b120069849f4d9309b60a4", "class_hash": "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8", "original_class_hash": "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8", "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", @@ -1646,7 +1673,7 @@ }, { "kind": "DojoContract", - "address": "0x54ff4297b599c8e3948093b96af1c030c153f58225d9e5310f7f0acb0d4a462", + "address": "0x58e03816d559f77fb131583f9a085a230096b698fa4e9fc66f4283f949e8fc5", "class_hash": "0x45ad5a298db270a9c3ee439b7a7a008e3219b70937cfaa144589866442f3908", "original_class_hash": "0x45ad5a298db270a9c3ee439b7a7a008e3219b70937cfaa144589866442f3908", "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", @@ -1883,7 +1910,7 @@ }, { "kind": "DojoContract", - "address": "0x6b85960481f204d313929031f776161d8b4eff4a8b9c53d14c27d7af90486d0", + "address": "0x151e10838dba3b957460cb87e60d09d4c897fec0dbb855a29fb5eaccd277cb", "class_hash": "0x3daab1621bba5f43f0d84f8f68ee7a5dfa4d83f98f746e2e9dcd3a848233e35", "original_class_hash": "0x3daab1621bba5f43f0d84f8f68ee7a5dfa4d83f98f746e2e9dcd3a848233e35", "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", @@ -2102,7 +2129,7 @@ }, { "kind": "DojoContract", - "address": "0x2c7763f16ffa3cc9b295904051b5b362ef99bf39eb0b43969ace5547e5bd64f", + "address": "0x740d37e05d5b0557da90efd55fa604103aedce66155869861fafc9fa2432bca", "class_hash": "0x647fc1b2d2e902e6304e127b36995d8f57fe45c38e38e15d8860db508dbf24a", "original_class_hash": "0x647fc1b2d2e902e6304e127b36995d8f57fe45c38e38e15d8860db508dbf24a", "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml index de5be0e6ee..08239b87f4 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml @@ -1,10 +1,10 @@ [world] kind = "WorldContract" -class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" -original_class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" +class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" +original_class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" abi = "manifests/dev/deployment/abis/dojo-world.json" -address = "0x64525f120f0c0bfaa610e38fad3ace40ff8c696e0c498697d73e0f58fd5ad1" -transaction_hash = "0x1a996413193677077362ecedda60227f345b0bb1b5c173b9a82f5cb8b584e8b" +address = "0xb91ef4f63e433b419ec4ec3647676f9c84d06bbcb16ff153fd911e6cb77f73" +transaction_hash = "0x6e759f50f367f4de947b3695d871db5584548c2f206ce49810f626b5fdbca9" block_number = 3 seed = "dojo_examples" manifest_name = "dojo-world" @@ -23,7 +23,7 @@ manifest_name = "dojo-base" [[contracts]] kind = "DojoContract" -address = "0x668a24b0352dec79bd4661685fe1b152f33989bd3dc2dbdb094491fb1bdd589" +address = "0x653b7e7bdc1596674dd81b7e4a61e859f9852d171b120069849f4d9309b60a4" class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" original_class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" @@ -40,7 +40,7 @@ manifest_name = "dojo_examples-actions-40b6994c" [[contracts]] kind = "DojoContract" -address = "0x54ff4297b599c8e3948093b96af1c030c153f58225d9e5310f7f0acb0d4a462" +address = "0x58e03816d559f77fb131583f9a085a230096b698fa4e9fc66f4283f949e8fc5" class_hash = "0x45ad5a298db270a9c3ee439b7a7a008e3219b70937cfaa144589866442f3908" original_class_hash = "0x45ad5a298db270a9c3ee439b7a7a008e3219b70937cfaa144589866442f3908" base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" @@ -54,7 +54,7 @@ manifest_name = "dojo_examples-dungeon-6620e0e6" [[contracts]] kind = "DojoContract" -address = "0x6b85960481f204d313929031f776161d8b4eff4a8b9c53d14c27d7af90486d0" +address = "0x151e10838dba3b957460cb87e60d09d4c897fec0dbb855a29fb5eaccd277cb" class_hash = "0x3daab1621bba5f43f0d84f8f68ee7a5dfa4d83f98f746e2e9dcd3a848233e35" original_class_hash = "0x3daab1621bba5f43f0d84f8f68ee7a5dfa4d83f98f746e2e9dcd3a848233e35" base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" @@ -68,7 +68,7 @@ manifest_name = "dojo_examples-mock_token-31599eb2" [[contracts]] kind = "DojoContract" -address = "0x2c7763f16ffa3cc9b295904051b5b362ef99bf39eb0b43969ace5547e5bd64f" +address = "0x740d37e05d5b0557da90efd55fa604103aedce66155869861fafc9fa2432bca" class_hash = "0x647fc1b2d2e902e6304e127b36995d8f57fe45c38e38e15d8860db508dbf24a" original_class_hash = "0x647fc1b2d2e902e6304e127b36995d8f57fe45c38e38e15d8860db508dbf24a" base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" diff --git a/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json b/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json index dbec675bc2..c5f374f4e0 100644 --- a/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json +++ b/examples/spawn-and-move/manifests/release/base/abis/dojo-world.json @@ -975,6 +975,33 @@ } ] }, + { + "type": "event", + "name": "dojo::world::world_contract::world::StoreUpdateMember", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "entity_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "member_selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, { "type": "event", "name": "dojo::world::world_contract::world::StoreDelRecord", @@ -1158,7 +1185,7 @@ }, { "name": "StoreUpdateMember", - "type": "dojo::world::world::StoreUpdateMember", + "type": "dojo::world::world_contract::world::StoreUpdateMember", "kind": "nested" }, { diff --git a/examples/spawn-and-move/manifests/release/base/dojo-world.toml b/examples/spawn-and-move/manifests/release/base/dojo-world.toml index 38bcc45608..c65bc0928d 100644 --- a/examples/spawn-and-move/manifests/release/base/dojo-world.toml +++ b/examples/spawn-and-move/manifests/release/base/dojo-world.toml @@ -1,6 +1,6 @@ kind = "Class" -class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" -original_class_hash = "0x32fb65ebfe6d91bb4b7ba0640650722c43ca0c917f5fc0f649ee2ecf720cde" +class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" +original_class_hash = "0x652c7e76b59d000bfbc6d5d16f58ee9a42ea25cb208c21281f97ea4fd6cbcc7" abi = "manifests/release/base/abis/dojo-world.json" tag = "dojo-world" manifest_name = "dojo-world" From 8805fa0f6e22f8be6ebc656e212685b696a657e5 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 13:18:47 -0400 Subject: [PATCH 24/35] fix: struct from ty as mutable --- .../torii/core/src/processors/store_update_member.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index ae52d438d9..5e910b48d7 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Error, Result}; use async_trait::async_trait; +use dojo_types::schema::Ty; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::naming; use dojo_world::contracts::world::WorldContractReader; @@ -57,13 +58,16 @@ where let member_selector = event.data[MEMBER_INDEX]; let model = db.model(selector).await?; - let schema = model.schema().await?; + let mut schema = model.schema().await?; + let struct_ = match &mut schema { + Ty::Struct(struct_) => Some(struct_), + _ => None, + }; - let mut member = schema - .as_struct() + let member = struct_ .expect("model schema must be a struct") .children - .iter() + .iter_mut() .find(|c| { get_selector_from_name(&c.name).expect("invalid selector for member name") == member_selector From c6bfb58c1634ac7a9186585e919d0f52aac487bb Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 13:20:38 -0400 Subject: [PATCH 25/35] fix: compilable torii --- crates/torii/core/src/sql.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 859f15f373..c5e5e7798e 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use chrono::Utc; use dojo_types::primitive::Primitive; -use dojo_types::schema::{EnumOption, Member, Struct, Ty}; +use dojo_types::schema::{EnumOption, Member, Ty}; use dojo_world::contracts::abi::model::Layout; use dojo_world::contracts::naming::compute_selector_from_names; use dojo_world::metadata::WorldMetadata; @@ -290,7 +290,7 @@ impl Sql { path, event_id, (&entity_id, is_event_message), - (&wrapped_ty, true), + (&entity, true), block_timestamp, &vec![], ); @@ -693,7 +693,7 @@ impl Sql { path_clone, event_id, (entity_id, is_event_message), - &member.ty, + (&member.ty, is_store_update_member), block_timestamp, indexes, ); @@ -733,7 +733,7 @@ impl Sql { path_clone, event_id, (entity_id, is_event_message), - &option.ty, + (&option.ty, is_store_update_member), block_timestamp, indexes, ); @@ -762,7 +762,7 @@ impl Sql { path_clone, event_id, (entity_id, is_event_message), - member, + (member, is_store_update_member), block_timestamp, indexes, ); @@ -800,7 +800,7 @@ impl Sql { path_clone, event_id, (entity_id, is_event_message), - member, + (member, is_store_update_member), block_timestamp, &indexes, ); From e4a734d7c91713a97ed524402532e389dbdc492c Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 14:06:31 -0400 Subject: [PATCH 26/35] feat: wrap up store update member --- .../src/processors/store_update_member.rs | 19 +++++++-------- crates/torii/core/src/sql.rs | 24 ++++++++++++------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 5e910b48d7..6e9d13c91e 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -1,6 +1,5 @@ use anyhow::{Context, Error, Result}; use async_trait::async_trait; -use dojo_types::schema::Ty; use dojo_world::contracts::model::ModelReader; use dojo_world::contracts::naming; use dojo_world::contracts::world::WorldContractReader; @@ -58,21 +57,19 @@ where let member_selector = event.data[MEMBER_INDEX]; let model = db.model(selector).await?; - let mut schema = model.schema().await?; - let struct_ = match &mut schema { - Ty::Struct(struct_) => Some(struct_), - _ => None, - }; + let schema = model.schema().await?; - let member = struct_ + let mut member = schema + .as_struct() .expect("model schema must be a struct") .children - .iter_mut() + .iter() .find(|c| { get_selector_from_name(&c.name).expect("invalid selector for member name") == member_selector }) - .context("member not found")?; + .context("member not found")? + .clone(); info!( target: LOG_TARGET, @@ -104,7 +101,9 @@ where member.ty.deserialize(&mut values)?; - db.set_entity(schema, event_id, block_timestamp).await?; + println!("member: {:?}", member); + + db.set_model_member(&schema.name(), entity_id, false, &member, event_id, block_timestamp).await?; Ok(()) } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index c5e5e7798e..b6f60465dd 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use chrono::Utc; use dojo_types::primitive::Primitive; -use dojo_types::schema::{EnumOption, Member, Ty}; +use dojo_types::schema::{EnumOption, Member, Struct, Ty}; use dojo_world::contracts::abi::model::Layout; use dojo_world::contracts::naming::compute_selector_from_names; use dojo_world::metadata::WorldMetadata; @@ -276,21 +276,25 @@ impl Sql { pub async fn set_model_member( &mut self, + model_tag: &str, entity_id: Felt, is_event_message: bool, - entity: &Ty, + member: &Member, event_id: &str, block_timestamp: u64, ) -> Result<()> { let entity_id = format!("{:#x}", entity_id); - let path = vec![entity.name()]; + let path = vec![model_tag.to_string()]; + + let wrapped_ty = + Ty::Struct(Struct { name: model_tag.to_string(), children: vec![member.clone()] }); // update model member self.build_set_entity_queries_recursive( path, event_id, (&entity_id, is_event_message), - (&entity, true), + (&wrapped_ty, true), block_timestamp, &vec![], ); @@ -658,15 +662,19 @@ impl Sql { let placeholders: Vec<&str> = arguments.iter().map(|_| "?").collect(); let statement = if is_store_update_member { + arguments.push(Argument::String(if is_event_message { + "event:".to_string() + entity_id + } else { + entity_id.to_string() + })); + // row has to exist. update it directly format!( - "UPDATE [{table_id}] SET {updates} WHERE entity_id = ?", + "UPDATE [{table_id}] SET {updates} WHERE id = ?", table_id = table_id, updates = columns .iter() - // skip id column - .skip(1) - .zip(placeholders.iter().skip(1)) + .zip(placeholders.iter()) .map(|(column, placeholder)| format!("{} = {}", column, placeholder)) .collect::>() .join(", ") From 1a585b540722f2a29ed515f06e9677e4cae5808a Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 14:06:47 -0400 Subject: [PATCH 27/35] fmt --- crates/torii/core/src/processors/store_update_member.rs | 3 ++- crates/torii/core/src/sql.rs | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 6e9d13c91e..8f791092b7 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -103,7 +103,8 @@ where println!("member: {:?}", member); - db.set_model_member(&schema.name(), entity_id, false, &member, event_id, block_timestamp).await?; + db.set_model_member(&schema.name(), entity_id, false, &member, event_id, block_timestamp) + .await?; Ok(()) } } diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index b6f60465dd..9e978282d8 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -710,11 +710,7 @@ impl Sql { Ty::Enum(e) => { if e.options.iter().all( |o| { - if let Ty::Tuple(t) = &o.ty { - t.is_empty() - } else { - false - } + if let Ty::Tuple(t) = &o.ty { t.is_empty() } else { false } }, ) { return; From d81a2d78fe19a3a8f0e9acb4977b409df71830e9 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 14:18:02 -0400 Subject: [PATCH 28/35] fix fmt --- bin/sozo/src/commands/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/sozo/src/commands/mod.rs b/bin/sozo/src/commands/mod.rs index 158fd8bfed..788d0b8fe2 100644 --- a/bin/sozo/src/commands/mod.rs +++ b/bin/sozo/src/commands/mod.rs @@ -53,8 +53,8 @@ pub enum Commands { Init(InitArgs), #[command(about = "Remove generated artifacts, manifests and abis")] Clean(CleanArgs), - #[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), #[command(about = "Developer mode: watcher for building and migration")] Dev(DevArgs), From ac8b09de7c81fa57b1107446e039fa7812bcff86 Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 14:18:50 -0400 Subject: [PATCH 29/35] fmt --- crates/katana/storage/provider/src/error.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/katana/storage/provider/src/error.rs b/crates/katana/storage/provider/src/error.rs index c02fda220d..3876bbeec7 100644 --- a/crates/katana/storage/provider/src/error.rs +++ b/crates/katana/storage/provider/src/error.rs @@ -73,9 +73,7 @@ pub enum ProviderError { /// Error when a contract nonce change entry is not found but the block number of when the /// change happen exists in the nonce change list. - #[error( - "Missing contract nonce change entry for contract {contract_address} at block {block}" - )] + #[error("Missing contract nonce change entry for contract {contract_address} at block {block}")] MissingContractNonceChangeEntry { /// The block number of when the change happen. block: BlockNumber, From 14861ad5ad6e23d84c0463a25ae154dd7e29995d Mon Sep 17 00:00:00 2001 From: Nasr Date: Tue, 30 Jul 2024 14:22:25 -0400 Subject: [PATCH 30/35] cairo fmt --- crates/dojo-core/src/world/world_contract.cairo | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/dojo-core/src/world/world_contract.cairo b/crates/dojo-core/src/world/world_contract.cairo index d81190697b..a84d4e7754 100644 --- a/crates/dojo-core/src/world/world_contract.cairo +++ b/crates/dojo-core/src/world/world_contract.cairo @@ -832,7 +832,10 @@ pub mod world { ModelIndex::MemberId(( entity_id, member_selector )) => { - self.write_model_member(model_selector, entity_id, member_selector, values, layout); + self + .write_model_member( + model_selector, entity_id, member_selector, values, layout + ); EventEmitter::emit( ref self, StoreUpdateMember { From a87133dc19786d704b8a785cef90820a051acc20 Mon Sep 17 00:00:00 2001 From: glihm Date: Tue, 30 Jul 2024 15:08:45 -0600 Subject: [PATCH 31/35] fix: update example to set array with new model API --- .../dojo_examples-actions-40b6994c.json | 24 ++++++++++++++-- .../dojo_examples-actions-40b6994c.toml | 4 +-- .../dojo_examples-actions-40b6994c.json | 24 ++++++++++++++-- .../manifests/dev/deployment/manifest.json | 28 +++++++++++++++---- .../manifests/dev/deployment/manifest.toml | 4 +-- .../dojo_examples-actions-40b6994c.json | 24 ++++++++++++++-- .../dojo_examples-actions-40b6994c.toml | 4 +-- examples/spawn-and-move/src/actions.cairo | 21 +++++++++----- examples/spawn-and-move/src/models.cairo | 2 +- 9 files changed, 107 insertions(+), 28 deletions(-) diff --git a/examples/spawn-and-move/manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json b/examples/spawn-and-move/manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json index 3d21bef6a6..ac6c7ed557 100644 --- a/examples/spawn-and-move/manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json +++ b/examples/spawn-and-move/manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json @@ -228,6 +228,24 @@ } ] }, + { + "type": "struct", + "name": "dojo_examples::models::PlayerItem", + "members": [ + { + "name": "item_id", + "type": "core::integer::u32" + }, + { + "name": "quantity", + "type": "core::integer::u32" + }, + { + "name": "score", + "type": "core::integer::i32" + } + ] + }, { "type": "interface", "name": "dojo_examples::actions::IActions", @@ -288,11 +306,11 @@ }, { "type": "function", - "name": "update_player_name_value", + "name": "update_player_items", "inputs": [ { - "name": "name", - "type": "core::byte_array::ByteArray" + "name": "items", + "type": "core::array::Array::" } ], "outputs": [], diff --git a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml index 36e30d588b..d6647ceeca 100644 --- a/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml +++ b/examples/spawn-and-move/manifests/dev/base/contracts/dojo_examples-actions-40b6994c.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" -original_class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" +class_hash = "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a" +original_class_hash = "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] diff --git a/examples/spawn-and-move/manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json b/examples/spawn-and-move/manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json index 3d21bef6a6..ac6c7ed557 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json +++ b/examples/spawn-and-move/manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json @@ -228,6 +228,24 @@ } ] }, + { + "type": "struct", + "name": "dojo_examples::models::PlayerItem", + "members": [ + { + "name": "item_id", + "type": "core::integer::u32" + }, + { + "name": "quantity", + "type": "core::integer::u32" + }, + { + "name": "score", + "type": "core::integer::i32" + } + ] + }, { "type": "interface", "name": "dojo_examples::actions::IActions", @@ -288,11 +306,11 @@ }, { "type": "function", - "name": "update_player_name_value", + "name": "update_player_items", "inputs": [ { - "name": "name", - "type": "core::byte_array::ByteArray" + "name": "items", + "type": "core::array::Array::" } ], "outputs": [], diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.json b/examples/spawn-and-move/manifests/dev/deployment/manifest.json index 50eb433801..c7d42bb7df 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.json +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.json @@ -1243,8 +1243,8 @@ { "kind": "DojoContract", "address": "0x24d926d75cd84104c3bd24f0f79e95c273d6a99ed449f3c8b83114857020332", - "class_hash": "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8", - "original_class_hash": "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8", + "class_hash": "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a", + "original_class_hash": "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a", "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", "abi": [ { @@ -1476,6 +1476,24 @@ } ] }, + { + "type": "struct", + "name": "dojo_examples::models::PlayerItem", + "members": [ + { + "name": "item_id", + "type": "core::integer::u32" + }, + { + "name": "quantity", + "type": "core::integer::u32" + }, + { + "name": "score", + "type": "core::integer::i32" + } + ] + }, { "type": "interface", "name": "dojo_examples::actions::IActions", @@ -1536,11 +1554,11 @@ }, { "type": "function", - "name": "update_player_name_value", + "name": "update_player_items", "inputs": [ { - "name": "name", - "type": "core::byte_array::ByteArray" + "name": "items", + "type": "core::array::Array::" } ], "outputs": [], diff --git a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml index 3b3d273383..064976b859 100644 --- a/examples/spawn-and-move/manifests/dev/deployment/manifest.toml +++ b/examples/spawn-and-move/manifests/dev/deployment/manifest.toml @@ -24,8 +24,8 @@ manifest_name = "dojo-base" [[contracts]] kind = "DojoContract" address = "0x24d926d75cd84104c3bd24f0f79e95c273d6a99ed449f3c8b83114857020332" -class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" -original_class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" +class_hash = "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a" +original_class_hash = "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a" base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" abi = "manifests/dev/deployment/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] diff --git a/examples/spawn-and-move/manifests/release/base/abis/contracts/dojo_examples-actions-40b6994c.json b/examples/spawn-and-move/manifests/release/base/abis/contracts/dojo_examples-actions-40b6994c.json index 3d21bef6a6..ac6c7ed557 100644 --- a/examples/spawn-and-move/manifests/release/base/abis/contracts/dojo_examples-actions-40b6994c.json +++ b/examples/spawn-and-move/manifests/release/base/abis/contracts/dojo_examples-actions-40b6994c.json @@ -228,6 +228,24 @@ } ] }, + { + "type": "struct", + "name": "dojo_examples::models::PlayerItem", + "members": [ + { + "name": "item_id", + "type": "core::integer::u32" + }, + { + "name": "quantity", + "type": "core::integer::u32" + }, + { + "name": "score", + "type": "core::integer::i32" + } + ] + }, { "type": "interface", "name": "dojo_examples::actions::IActions", @@ -288,11 +306,11 @@ }, { "type": "function", - "name": "update_player_name_value", + "name": "update_player_items", "inputs": [ { - "name": "name", - "type": "core::byte_array::ByteArray" + "name": "items", + "type": "core::array::Array::" } ], "outputs": [], diff --git a/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml b/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml index 6c912bbe36..a12c96a2e4 100644 --- a/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml +++ b/examples/spawn-and-move/manifests/release/base/contracts/dojo_examples-actions-40b6994c.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" -original_class_hash = "0x5d3ffcdabbf541ac1ce9df26f275d6abaec2c260d7a698e1c94a4bd1a0482b8" +class_hash = "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a" +original_class_hash = "0x2a8de224c28cae3049e23b352e7fce6f26cc99884331e5f2a6aea261398a27a" base_class_hash = "0x0" abi = "manifests/release/base/abis/contracts/dojo_examples-actions-40b6994c.json" reads = [] diff --git a/examples/spawn-and-move/src/actions.cairo b/examples/spawn-and-move/src/actions.cairo index b966441e49..64248db5d2 100644 --- a/examples/spawn-and-move/src/actions.cairo +++ b/examples/spawn-and-move/src/actions.cairo @@ -1,4 +1,4 @@ -use dojo_examples::models::{Direction, Position, Vec2}; +use dojo_examples::models::{Direction, Position, Vec2, PlayerItem}; #[dojo::interface] pub trait IActions { @@ -7,7 +7,7 @@ pub trait IActions { fn set_player_config(ref world: IWorldDispatcher, name: ByteArray); fn get_player_position(world: @IWorldDispatcher) -> Position; fn update_player_name(ref world: IWorldDispatcher, name: ByteArray); - fn update_player_name_value(ref world: IWorldDispatcher, name: ByteArray); + fn update_player_items(ref world: IWorldDispatcher, items: Array); fn reset_player_config(ref world: IWorldDispatcher); fn set_player_server_profile(ref world: IWorldDispatcher, server_id: u32, name: ByteArray); #[cfg(feature: 'dungeon')] @@ -28,7 +28,7 @@ pub mod actions { use starknet::{ContractAddress, get_caller_address}; use dojo_examples::models::{ Position, Moves, Direction, Vec2, PlayerConfig, PlayerItem, ServerProfile, PositionStore, - MovesStore, MovesEntityStore, PlayerConfigStore, PlayerConfigEntityStore + MovesStore, MovesEntityStore, PlayerConfigStore, PlayerConfigEntityStore, }; use dojo_examples::utils::next_position; @@ -177,15 +177,22 @@ pub mod actions { assert(new_name == name, 'unable to change name'); } - fn update_player_name_value(ref world: IWorldDispatcher, name: ByteArray) { + fn update_player_items(ref world: IWorldDispatcher, items: Array) { let player = get_caller_address(); let config_id = PlayerConfigStore::entity_id_from_keys(player); + let items_clone = items.clone(); + let config = PlayerConfigEntityStore::get(world, config_id); - config.set_name(world, name.clone()); + config.set_items(world, items); - let new_name = PlayerConfigEntityStore::get_name(world, config_id); - assert(new_name == name, 'unable to change name'); + let new_items = PlayerConfigEntityStore::get_items(world, config_id); + let mut size = items_clone.len(); + + while size > 0 { + assert(new_items.at(size - 1) == items_clone.at(size - 1), 'item not found'); + size -= 1; + } } } diff --git a/examples/spawn-and-move/src/models.cairo b/examples/spawn-and-move/src/models.cairo index ddd61efb92..094ec84eab 100644 --- a/examples/spawn-and-move/src/models.cairo +++ b/examples/spawn-and-move/src/models.cairo @@ -70,7 +70,7 @@ pub struct Position { // Every field inside a model must derive `Introspect` or `IntrospectPacked`. // `IntrospectPacked` can also be used into models that are only using `Introspect`. -#[derive(Copy, Drop, Serde, Introspect)] +#[derive(Copy, Drop, Serde, Introspect, PartialEq)] pub struct PlayerItem { pub item_id: u32, pub quantity: u32, From 92ec2feca0031742d20139867a8c20e4bcdaf891 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 31 Jul 2024 10:40:57 -0400 Subject: [PATCH 32/35] fix: handle arrays --- crates/torii/core/src/sql.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index 9e978282d8..a958d69052 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -661,7 +661,7 @@ impl Sql { } let placeholders: Vec<&str> = arguments.iter().map(|_| "?").collect(); - let statement = if is_store_update_member { + let statement = if is_store_update_member && !indexes.is_empty() { arguments.push(Argument::String(if is_event_message { "event:".to_string() + entity_id } else { From d6c939e67fc71c761c4065a186fa437328df75a9 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 31 Jul 2024 11:03:20 -0400 Subject: [PATCH 33/35] fix: correctly handle arrays --- crates/torii/core/src/sql.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/torii/core/src/sql.rs b/crates/torii/core/src/sql.rs index a958d69052..776f3754ea 100644 --- a/crates/torii/core/src/sql.rs +++ b/crates/torii/core/src/sql.rs @@ -661,7 +661,7 @@ impl Sql { } let placeholders: Vec<&str> = arguments.iter().map(|_| "?").collect(); - let statement = if is_store_update_member && !indexes.is_empty() { + let statement = if is_store_update_member && indexes.is_empty() { arguments.push(Argument::String(if is_event_message { "event:".to_string() + entity_id } else { From 652a1f4e837aca2501f81b285cfb2e3a6dc9e92b Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 31 Jul 2024 11:13:21 -0400 Subject: [PATCH 34/35] chore --- crates/torii/core/src/processors/store_update_member.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/torii/core/src/processors/store_update_member.rs b/crates/torii/core/src/processors/store_update_member.rs index 8f791092b7..a7ddcab839 100644 --- a/crates/torii/core/src/processors/store_update_member.rs +++ b/crates/torii/core/src/processors/store_update_member.rs @@ -101,8 +101,6 @@ where member.ty.deserialize(&mut values)?; - println!("member: {:?}", member); - db.set_model_member(&schema.name(), entity_id, false, &member, event_id, block_timestamp) .await?; Ok(()) From 72cc8df91c1f0ac9c62089bd416fad8306fc0978 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 31 Jul 2024 12:25:31 -0400 Subject: [PATCH 35/35] fix: test --- crates/sozo/ops/src/tests/model.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sozo/ops/src/tests/model.rs b/crates/sozo/ops/src/tests/model.rs index 7255804af1..cc7a871b92 100644 --- a/crates/sozo/ops/src/tests/model.rs +++ b/crates/sozo/ops/src/tests/model.rs @@ -37,7 +37,7 @@ async fn test_model_ops() { ) .await .unwrap(), - Felt::from_hex("0x2b14bbb22e6a21cc949e06a187436c96aeab0e0290b3a8d91fb357ed2e6d973") + Felt::from_hex("0x4eddd8563a17c7d256b35e3cb0decdfcdfe122dd72593ebc572cfc535941ac2") .unwrap() );