Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(torii-core): store update member #2182

Merged
merged 38 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
98801d3
feat(torii-core): store update member
Larkooo Jul 17, 2024
3f6908e
feat; add set_model_member for updating specific member
Larkooo Jul 17, 2024
8aba41c
chore: format
Larkooo Jul 17, 2024
65b2c39
chore: update log to include member nname
Larkooo Jul 17, 2024
b54901c
fmt
Larkooo Jul 17, 2024
349b327
refactor: clean code & add is event message
Larkooo Jul 17, 2024
9dd48d8
fmt
Larkooo Jul 17, 2024
b0d9fd5
chore
Larkooo Jul 17, 2024
71af001
feat: emit the store member update from the world
glihm Jul 18, 2024
9343249
fix: ensure event messages are emitted with the correct selector
glihm Jul 18, 2024
a900617
merge main
glihm Jul 18, 2024
acf7c60
fix: cairo fmt
glihm Jul 18, 2024
8bcaf36
fix: fix test typo
glihm Jul 18, 2024
91949d5
wip:
glihm Jul 18, 2024
7fa5f5a
fix: simple types model memebr update
Larkooo Jul 18, 2024
8d14285
chore; pass memmber type to func
Larkooo Jul 18, 2024
7e4c56c
chore: clean code
Larkooo Jul 18, 2024
6f23b9a
fmt
Larkooo Jul 18, 2024
59736ee
wip
Larkooo Jul 19, 2024
98b7d48
fix: upsert to avoid constraint CHECK failing
Larkooo Jul 19, 2024
5d8e141
fmt
Larkooo Jul 19, 2024
ba34cd3
Merge remote-tracking branch 'upstream/main' into store-update-member
Larkooo Jul 29, 2024
2e87cde
fix: figure out way to fix upsert issue to reuse func
Larkooo Jul 29, 2024
ddb37c3
refactor: refactor recursive set to handle store update member
Larkooo Jul 29, 2024
ac41ee0
fix: fix world typo and merge
glihm Jul 30, 2024
58eef8d
merge main
glihm Jul 30, 2024
8805fa0
fix: struct from ty as mutable
Larkooo Jul 30, 2024
c6bfb58
fix: compilable torii
Larkooo Jul 30, 2024
e4a734d
feat: wrap up store update member
Larkooo Jul 30, 2024
1a585b5
fmt
Larkooo Jul 30, 2024
d81a2d7
fix fmt
Larkooo Jul 30, 2024
ac8b09d
fmt
Larkooo Jul 30, 2024
14861ad
cairo fmt
Larkooo Jul 30, 2024
a87133d
fix: update example to set array with new model API
glihm Jul 30, 2024
92ec2fe
fix: handle arrays
Larkooo Jul 31, 2024
d6c939e
fix: correctly handle arrays
Larkooo Jul 31, 2024
652a1f4
chore
Larkooo Jul 31, 2024
72cc8df
fix: test
Larkooo Jul 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/torii/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;
Expand Down Expand Up @@ -172,6 +173,7 @@
Box::new(StoreDelRecordProcessor),
Box::new(EventMessageProcessor),
Box::new(StoreUpdateRecordProcessor),
Box::new(StoreUpdateMemberProcessor),

Check warning on line 176 in bin/torii/src/main.rs

View check run for this annotation

Codecov / codecov/patch

bin/torii/src/main.rs#L176

Added line #L176 was not covered by tests
glihm marked this conversation as resolved.
Show resolved Hide resolved
],
transaction: vec![Box::new(StoreTransactionProcessor)],
..Processors::default()
Expand Down
1 change: 1 addition & 0 deletions crates/torii/core/src/processors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod register_model;
pub mod store_del_record;
pub mod store_set_record;
pub mod store_transaction;
pub mod store_update_member;
pub mod store_update_record;

const MODEL_INDEX: usize = 0;
Expand Down
99 changes: 99 additions & 0 deletions crates/torii/core/src/processors/store_update_member.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
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;

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

const MEMBER_INDEX: usize = 2;

#[derive(Default, Debug)]
pub struct StoreUpdateMemberProcessor;

#[async_trait]
impl<P> EventProcessor<P> for StoreUpdateMemberProcessor
where
P: Provider + Send + Sync + std::fmt::Debug,
{
fn event_key(&self) -> String {
"StoreUpdateMember".to_string()
}

Check warning on line 30 in crates/torii/core/src/processors/store_update_member.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/store_update_member.rs#L28-L30

Added lines #L28 - L30 were not covered by tests

fn validate(&self, event: &Event) -> bool {
if event.keys.len() > 1 {
info!(

Check warning on line 34 in crates/torii/core/src/processors/store_update_member.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/store_update_member.rs#L32-L34

Added lines #L32 - L34 were not covered by tests
target: LOG_TARGET,
event_key = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_key(self),
invalid_keys = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_keys_as_string(self, event),
"Invalid event keys."

Check warning on line 38 in crates/torii/core/src/processors/store_update_member.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/store_update_member.rs#L36-L38

Added lines #L36 - L38 were not covered by tests
);
return false;
}
true
}

Check warning on line 43 in crates/torii/core/src/processors/store_update_member.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/store_update_member.rs#L40-L43

Added lines #L40 - L43 were not covered by tests

async fn process(
&self,
_world: &WorldContractReader<P>,
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 member_selector = event.data[MEMBER_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 = MEMBER_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 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
}

Check warning on line 98 in crates/torii/core/src/processors/store_update_member.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/processors/store_update_member.rs#L54-L98

Added lines #L54 - L98 were not covered by tests
Copy link

Choose a reason for hiding this comment

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

Comprehensive implementation of StoreUpdateMemberProcessor.

The processor is well-implemented with methods for event validation and processing. However, the codecov warnings indicate missing test coverage which is crucial for ensuring the functionality works as expected.

+ // TODO: Add unit tests to cover the new functionality.

Would you like me to help in writing some initial unit tests or open a GitHub issue to track this task?

Committable suggestion

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

Suggested change
pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record";
const MEMBER_INDEX: usize = 2;
#[derive(Default, Debug)]
pub struct StoreUpdateMemberProcessor;
#[async_trait]
impl<P> EventProcessor<P> 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 = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_key(self),
invalid_keys = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_keys_as_string(self, event),
"Invalid event keys."
);
return false;
}
true
}
async fn process(
&self,
_world: &WorldContractReader<P>,
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 member_selector = event.data[MEMBER_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 = MEMBER_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 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
}
pub(crate) const LOG_TARGET: &str = "torii_core::processors::store_update_record";
const MEMBER_INDEX: usize = 2;
#[derive(Default, Debug)]
pub struct StoreUpdateMemberProcessor;
#[async_trait]
impl<P> EventProcessor<P> 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 = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_key(self),
invalid_keys = %<StoreUpdateMemberProcessor as EventProcessor<P>>::event_keys_as_string(self, event),
"Invalid event keys."
);
return false;
}
true
}
async fn process(
&self,
_world: &WorldContractReader<P>,
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 member_selector = event.data[MEMBER_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 = MEMBER_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 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
}
}
// TODO: Add unit tests to cover the new functionality.
Tools
GitHub Check: codecov/patch

[warning] 28-30: crates/torii/core/src/processors/store_update_member.rs#L28-L30
Added lines #L28 - L30 were not covered by tests


[warning] 32-34: crates/torii/core/src/processors/store_update_member.rs#L32-L34
Added lines #L32 - L34 were not covered by tests


[warning] 36-38: crates/torii/core/src/processors/store_update_member.rs#L36-L38
Added lines #L36 - L38 were not covered by tests


[warning] 40-43: crates/torii/core/src/processors/store_update_member.rs#L40-L43
Added lines #L40 - L43 were not covered by tests


[warning] 54-98: crates/torii/core/src/processors/store_update_member.rs#L54-L98
Added lines #L54 - L98 were not covered by tests

}
25 changes: 24 additions & 1 deletion crates/torii/core/src/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,29 @@
Ok(())
}

pub async fn set_model_member(
Copy link

Choose a reason for hiding this comment

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

Ohayo, Sensei! Reminder: Add tests.

The set_model_member function is well-implemented and crucial for updating model members. However, it lacks test coverage, which is essential for ensuring its reliability and correctness.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

&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(
Larkooo marked this conversation as resolved.
Show resolved Hide resolved
path,
&entity_id,
(&entity_id, false),
member,
block_timestamp,
&vec![],
);
self.query_queue.execute_all().await?;

Check warning on line 292 in crates/torii/core/src/sql.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql.rs#L274-L292

Added lines #L274 - L292 were not covered by tests

Ok(())
}

Check warning on line 295 in crates/torii/core/src/sql.rs

View check run for this annotation

Codecov / codecov/patch

crates/torii/core/src/sql.rs#L294-L295

Added lines #L294 - L295 were not covered by tests
Copy link

Choose a reason for hiding this comment

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

Robust implementation of set_model_member.

The function is well-implemented and crucial for updating model members. However, it lacks test coverage, which is essential for ensuring its reliability and correctness.

+ // TODO: Add unit tests to cover `set_model_member`.

Would you like assistance in creating unit tests for this function, or should I open a GitHub issue to track this task?

Committable suggestion

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

Suggested change
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 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(())
}
// TODO: Add unit tests to cover `set_model_member`.
Tools
GitHub Check: codecov/patch

[warning] 274-292: crates/torii/core/src/sql.rs#L274-L292
Added lines #L274 - L292 were not covered by tests


[warning] 294-295: crates/torii/core/src/sql.rs#L294-L295
Added lines #L294 - L295 were not covered by tests


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()];
Expand Down Expand Up @@ -556,7 +579,7 @@
}
}

fn build_set_entity_queries_recursive(
pub fn build_set_entity_queries_recursive(
&mut self,
path: Vec<String>,
event_id: &str,
Expand Down
Loading