-
Notifications
You must be signed in to change notification settings - Fork 176
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: check models and events upgradability #2626
Conversation
WalkthroughOhayo, sensei! This pull request introduces significant changes across various files in the Dojo framework. Key updates include a transition of dependencies in Changes
Possibly related PRs
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 18
🧹 Outside diff range and nitpick comments (43)
crates/dojo/core/src/contract/interface.cairo (2)
2-2
: Consider adding documentation about trait's purpose.Even though the trait is empty, it might serve as a marker interface. Adding documentation would help explain its role in the new architecture.
#[starknet::interface] +/// Marker trait for Dojo contracts after removal of versioning management. +/// This trait is intentionally empty as contract identification is now handled +/// through the new resource management system. pub trait IContract<T> {}
2-2
: Provide migration guidance for existing implementations.Since this is a breaking change that removes functionality, consider adding migration documentation to help users update their code to use the new resource management system.
Would you like me to help draft migration documentation or create a GitHub issue to track this task?
crates/dojo/core/src/model/interface.cairo (1)
Line range hint
1-11
: Document the interface changes, sensei!The removal of
dojo_name
,version
,layout
, andschema
methods represents a significant change to the interface. Consider updating the doc comments to:
- Explain why these methods were removed
- Document how the upgradability checks work
- Guide users on handling model upgrades
/// The `IModel` starknet interface. /// /// This is the interface used by offchain components and other contracts - /// to interact with deployed models. + /// to interact with deployed models. + /// + /// # Model Upgrades + /// Models can be upgraded by deploying a new classhash while following these rules: + /// - Layout type (Struct/Fixed) must remain the same + /// - Existing fields cannot be changed or moved + /// - New fields can only be appended at the endcrates/dojo/core/src/event/event.cairo (1)
11-21
: Architectural consideration for event upgradability, sensei!The switch to
Struct
return type forschema()
provides better structural guarantees for event upgradability checks. This change will help enforce the conditions mentioned in the PR objectives:
- Maintaining the same layout type
- Preventing changes to existing fields
- Allowing new fields only at the end
Consider adding documentation that explicitly states these upgrade constraints in the trait documentation. Would you like me to provide a suggested documentation block?
crates/dojo/core/src/meta/interface.cairo (2)
4-11
: Excellent interface design, sensei!The
IDeployedResource
interface is well-documented and follows the single responsibility principle. Thedojo_name
method will be crucial for resource identification during upgrades.Consider documenting the expected format or constraints of the returned ByteArray in the method documentation, if any exist.
13-21
: Well-structured interface for upgrade validation, sensei!The
IStoredResource
interface is perfectly aligned with the PR objectives, providing methods to verify upgrade constraints (layout type consistency and field positions).Consider enhancing the documentation with:
- Method-level documentation explaining the purpose of
layout
andschema
- Examples of how these methods support upgrade validation
- Return value descriptions
/// The `IStoredResource` starknet interface. /// /// This is the interface used by offchain components and other contracts /// to access to storage related data of a deployed resource. #[starknet::interface] pub trait IStoredResource<T> { + /// Returns the layout type (Struct or Fixed) of the resource. + /// Used to ensure layout consistency during upgrades. fn layout(self: @T) -> Layout; + + /// Returns the resource's schema definition. + /// Used to validate field positions and additions during upgrades. fn schema(self: @T) -> Struct; }crates/dojo/core/src/model/component.cairo (2)
5-11
: Clean separation of deployed model concerns, sensei!The introduction of
IDeployedModelImpl
effectively separates the deployed model interface, which is crucial for the new upgradability system. Thedojo_name
method provides a stable identifier for models across upgrades.This separation of deployed and stored model traits provides a solid foundation for managing model upgrades while maintaining consistent identification.
Line range hint
27-39
: Clean removal of versioning, sensei!The implementation correctly removes the version management while maintaining essential model metadata methods. This aligns perfectly with the PR objective to remove versioning management from the system.
The retained methods (
unpacked_size
,packed_size
, anddefinition
) provide sufficient metadata for model management without the complexity of version tracking.crates/dojo/core/src/model/definition.cairo (1)
32-34
: Confirm removal of versioning is handled properly.The removal of the version field from ModelDef aligns with the PR objective to remove versioning management. However, we should ensure this change is handled gracefully in existing deployments.
Consider documenting the migration path for existing deployments that might be relying on version information. This could include:
- How to handle existing deployed models with versions
- Guidelines for upgrading without version checks
- New upgrade validation rules based on layout and field positions
crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo (1)
18-24
: Nice refactoring of contract implementations, sensei!The changes effectively:
- Remove versioning through the empty
IContract
implementation- Add resource identification via
IDeployedResource
implementationThis aligns perfectly with the PR's goal of removing versioning while enhancing upgradability management.
Consider documenting these changes in the module-level documentation to help other developers understand the new contract lifecycle and resource management approach.
crates/dojo/core/src/meta/layout.cairo (2)
25-38
: Ohayo! The implementation looks clean and effective, sensei!The
is_same_type_of
implementation correctly handles all Layout variants and provides a solid foundation for upgradability checks. However, consider adding documentation to explain its role in the upgrade process.Add documentation above the trait:
+/// Trait for comparing Layout types during resource upgrades. +/// Used to ensure that new versions maintain the same layout type as their predecessors. #[generate_trait] pub impl LayoutCompareImpl of LayoutCompareTrait {
27-37
: Consider enhancing type comparison for stricter validation, sensei!While the current implementation checks layout types, it might be beneficial to add methods for comparing internal structures (e.g., field order in Struct, array element types) to enforce the PR's requirement that "existing fields cannot be changed or moved".
Consider adding a method like:
fn is_compatible_with(self: @Layout, old: @Layout) -> bool { if !self.is_same_type_of(old) { return false; } match (self, old) { (Layout::Struct(new_fields), Layout::Struct(old_fields)) => { // Check if old fields exist in same order if old_fields.len() > new_fields.len() { return false; } let mut i = 0; loop { if i >= old_fields.len() { break true; } if new_fields[i] != old_fields[i] { break false; } i += 1; } }, // Add similar checks for other variants _ => true } }crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (1)
64-64
: Nice architectural split of event implementations, sensei!The separation into
DeployedEventImpl
,StoredEventImpl
, andEventImpl
provides better modularity and clearer responsibility boundaries. This change aligns with the removal of versioning while maintaining proper event handling capabilities.Consider documenting the specific responsibilities of each implementation type in the module-level documentation to help other developers understand when to use each variant.
Also applies to: 66-67, 69-70
crates/dojo/core-cairo-test/src/lib.cairo (2)
43-50
: Ohayo! Clean modular structure for test helpers!The new helpers module provides a well-organized structure for test utilities. The exports are clearly named and follow good patterns for test resources.
Consider grouping the exports by their purpose (e.g., contracts, models, utilities) to make it even more maintainable as the test suite grows.
72-78
: Clean up commented modules, sensei!While the new module structure looks good, there are some commented-out module declarations that should be addressed:
//mod entities;
//mod world;
Either remove them if they're no longer needed or add a TODO comment explaining why they're kept.
crates/dojo/core-cairo-test/src/tests/world/namespace.cairo (3)
6-30
: Well-structured test with comprehensive assertions, sensei!The test thoroughly verifies both state changes and event emissions. Consider extracting the test address
0xb0b
to a constant for reuse across tests.+const BOB_ADDRESS: felt252 = 0xb0b; + #[test] fn test_register_namespace() { let world = deploy_world(); - let bob = starknet::contract_address_const::<0xb0b>(); + let bob = starknet::contract_address_const::<BOB_ADDRESS>(); starknet::testing::set_account_contract_address(bob);
32-43
: Consider extracting common setup code, sensei!The setup code is duplicated across tests. Consider creating a helper function to reduce duplication.
+fn setup_test_caller(address: felt252) -> IWorldDispatcher { + let world = deploy_world(); + let caller = starknet::contract_address_const::<address>(); + starknet::testing::set_account_contract_address(caller); + starknet::testing::set_contract_address(caller); + world +} + #[test] #[should_panic(expected: ("Namespace `namespace` is already registered", 'ENTRYPOINT_FAILED',))] fn test_register_namespace_already_registered_same_caller() { - let world = deploy_world(); - - let bob = starknet::contract_address_const::<0xb0b>(); - starknet::testing::set_account_contract_address(bob); - starknet::testing::set_contract_address(bob); + let world = setup_test_caller(BOB_ADDRESS);
64-76
: Consider expanding invalid namespace test cases, sensei!While testing empty namespace is good, consider adding more test cases for invalid characters based on the regex pattern
^[a-zA-Z0-9_]+$
.Would you like me to help generate additional test cases for invalid namespaces? For example:
- Spaces in name
- Special characters
- Starting with numbers
- Unicode characters
Also, the gas limit of 6000000 seems high for a validation test. Consider profiling to determine a more appropriate limit.
crates/dojo/core/src/lib.cairo (1)
25-30
: Ohayo! The new resource interfaces look well-structured.The introduction of
IDeployedResource
andIStoredResource
interfaces aligns perfectly with the PR's objective of implementing upgradability checks. These interfaces will help manage the upgrade process by providing clear contracts for deployed and stored resources.Consider adding documentation comments to explain the upgrade constraints (same layout type, no field changes/movements, append-only new fields) directly in these interfaces.
crates/dojo/core/src/world/errors.cairo (1)
85-87
: Consider adding more context to the layout upgrade error message.While the message is consistent with other errors, it could be more helpful by indicating what makes the layout invalid (e.g., whether it's due to field reordering, type changes, etc.).
- format!("Invalid new layout to upgrade the resource `{}-{}`", namespace, name) + format!("Invalid new layout to upgrade the resource `{}-{}`. Layout type must remain the same and existing fields cannot be modified", namespace, name)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo (3)
6-17
: Consider adding event verification.The test validates metadata storage but doesn't verify if the appropriate MetadataUpdate event was emitted. Consider adding event verification similar to the one in
test_set_metadata_resource_owner
.world.set_metadata(metadata.clone()); assert(world.metadata(0) == metadata, 'invalid metadata'); + +let event = starknet::testing::pop_log::<world::Event>(world.contract_address); +assert(event.is_some(), 'no event'); + +if let world::Event::MetadataUpdate(event) = event.unwrap() { + assert(event.resource == metadata.resource_id, 'bad resource'); + assert(event.uri == metadata.metadata_uri, 'bad uri'); +}
52-74
: Consider adding post-failure metadata verification.While the test correctly verifies that writers cannot set metadata, it would be valuable to assert that the metadata remains unchanged after the failed attempt.
+let original_metadata = world.metadata(model_selector); world.set_metadata(metadata.clone()); +assert(world.metadata(model_selector) == original_metadata, 'metadata changed');
96-114
: Consider enhancing security test documentation.While the test effectively validates protection against malicious contracts, it would be valuable to add comments explaining:
- Why contract deployment status is checked
- The potential security implications of allowing non-deployed contracts
+ // Even if an account has owner permissions, they cannot update metadata + // through a non-deployed contract address. This prevents potential + // security risks from malicious contracts masquerading as legitimate ones. world.set_metadata(metadata.clone());crates/dojo/core/src/model/model.cairo (1)
Line range hint
91-109
: Consider documenting the upgradability constraints, sensei!The removal of versioning and the switch to
Struct
type supports the new upgradability checks. However, since this is a core change in how models can be upgraded, consider adding documentation about:
- The requirement to maintain the same layout type
- The prohibition of modifying existing fields
- The rule about appending new fields only at the end
This will help developers understand the constraints when designing their models for future upgradability.
crates/dojo/core-cairo-test/src/tests/contract.cairo (1)
64-68
: Excellent implementation of IDeployedResource, sensei!The new
Contract_DeployedContractImpl
implementation properly identifies the contract as a deployed resource, which is essential for the new upgradability system.Consider adding a brief comment explaining that this is a test implementation, like:
#[abi(embed_v0)] +// Test implementation of IDeployedResource for contract upgradability testing pub impl Contract_DeployedContractImpl of IDeployedResource<ContractState> {
crates/torii/types-test/src/contracts.cairo (1)
Line range hint
139-152
: Ohayo! Some concerns about the delete implementation, sensei!The delete function has several issues that need attention:
- The assumption that
subrecord_id = record_id + 1
is unsafe and might lead to incorrect deletions- Missing error handling for non-existent records
- No events are emitted for tracking deletion operations
- No transaction safety if deletion fails midway
Here's a suggested improvement:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); + // Verify record exists before proceeding + assert(world.model_exists<Record>(record_id), 'Record does not exist'); + let record: Record = world.read_model(record_id); let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; + // Read all subrecords associated with this record_id + let subrecords = world.get_models<Subrecord>((record_id)); world.erase_model(@record); world.erase_model(@record_sibling); - world.erase_model(@subrecord); + // Delete all associated subrecords + subrecords.iter().for_each(|subrecord| { + world.erase_model(@subrecord); + }); + // Emit deletion event + world.emit_event( + @RecordDeleted { record_id } + ); }Would you like me to help create a GitHub issue to track these improvements?
crates/dojo/lang/src/attribute_macros/element.rs (1)
Line range hint
16-23
: Ohayo! Consider updating the trait documentation, sensei.With the removal of versioning, the documentation for
StructParameterParser
should be updated to reflect that it now focuses solely on model and event attribute parsing without version management.crates/dojo/lang/src/attribute_macros/event.rs (1)
56-63
: Consider enhancing the warning message with valid parameter options.The warning message could be more helpful by listing the valid parameters that are supported.
- "Unexpected parameter {} for {attribute_name}.", + "Unexpected parameter {} for {attribute_name}. Only 'historical' parameter is supported.",crates/dojo/lang/src/attribute_macros/model.rs (3)
Line range hint
31-70
: Consider adding upgradability validation checks, sensei!While the existing validation logic is solid, consider adding checks to enforce the upgradability constraints mentioned in the PR objectives:
- Validate layout type consistency (Struct/Fixed)
- Ensure no modifications to existing field positions
- Verify new fields are only appended at the end
This would prevent invalid model upgrades at compile-time rather than runtime.
Would you like help implementing these additional validation checks?
Line range hint
72-185
: Add documentation about upgradability implications.The code generation logic is robust, but it would be helpful to add documentation explaining:
- How the generated code handles model upgrades
- Impact on storage layout
- Compatibility considerations for existing deployments
This documentation would be valuable for developers implementing upgradeable models.
Example documentation to add above the
from_struct
function:/// Generates code for a Dojo model, ensuring upgradability constraints: /// - Maintains layout type consistency (Struct/Fixed) /// - Preserves existing field positions /// - Allows new fields only at the end of the resource /// /// Note: Model versioning is not supported as upgrades are handled through /// classhash deployment while maintaining backward compatibility.
Line range hint
187-208
: Consider documenting accessor stability guarantees.The field accessor generation is solid, but it would be helpful to document that:
- Field selectors remain stable across upgrades
- Accessors maintain backward compatibility
- New fields don't affect existing accessor behavior
This helps developers understand the implications of model upgrades on their accessor usage.
crates/dojo/core/src/event/component.cairo (1)
26-31
: Ohayo, sensei! Consider adding documentation comments toIEventImpl
for clarity.Including documentation comments for the
definition
method would enhance readability and assist other developers in understanding its purpose and usage.Apply this diff to add a documentation comment:
pub impl IEventImpl<TContractState, E, +Event<E>> of IEvent<TContractState> { + /// Returns the event definition containing name, schema, and layout. fn definition(self: @TContractState) -> EventDefinition { Event::<E>::definition() } }
crates/dojo/core/src/meta/introspect.cairo (1)
49-59
: Consider using afor
loop for cleaner iterationOhayo, sensei! To enhance readability and follow idiomatic practices, you might replace the manual
loop
with afor
loop that iterates over the indices ofold.children
.Here's how you could refactor the code:
let mut i = 0; -loop { - if i >= (*old.children).len() { - break true; - } - - if *old.children[i] != *self.children[i] { - break false; - } - - i += 1; -} +for i in 0..(*old.children).len() { + if *old.children[i] != *self.children[i] { + return false; + } +} +return true;crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (3)
7-10
: Ohayo, sensei! Typo in comment: 'differenciate' should be 'differentiate'There's a misspelling in the comment. The correct spelling is "differentiate."
80-228
: Ohayo, sensei! Consider refactoring to reduce code duplication in modulesThe implementations of
DeployedEventImpl
andStoredImpl
are similar across different modules. Refactoring these implementations could improve maintainability and reduce repetition.
100-100
: Enhance panic messages for better debuggingConsider providing more informative panic messages to aid in identifying issues during runtime.
For example, in line
100~
:- panic!("Unexpected schema.") + panic!("Unexpected schema: expected a struct type for FooEventBadLayoutType.")Also applies to: 130-130, 160-160, 190-190, 220-220
crates/dojo/core-cairo-test/src/tests/world/event.cairo (3)
13-16
: Refactor repeated setup code into a helper functionOhayo, sensei! I noticed that the setup code for initializing
bob
and deploying the world is repeated in multiple test functions. To enhance maintainability and reduce duplication, consider refactoring this code into a helper function.Here's an example of how you could refactor:
fn setup_bob_as_owner() -> (ContractAddress, IWorldDispatcherTrait) { let bob = starknet::contract_address_const::<0xb0b>(); let world = deploy_world(); world.grant_owner(DOJO_NSH, bob); (bob, world) }Then, in your test functions, you can use:
let (bob, world) = setup_bob_as_owner();Also applies to: 50-53
25-25
: Fix typo in assertion messageOhayo, sensei! There's a small typo in your assertion message. The closing parenthesis is unnecessary.
Please update the assertion as follows:
- assert(event.is_some(), 'no event)'); + assert(event.is_some(), 'no event');
77-77
: Fix typo in assertion messageOhayo, sensei! Found another small typo in your assertion message.
Please correct it as follows:
- assert(event.is_some(), 'no event)'); + assert(event.is_some(), 'no event');crates/dojo/core/src/world/world_contract.cairo (2)
975-1011
: Ohayo sensei! Theassert_resource_upgradability
function strengthens upgradesImplementing
assert_resource_upgradability
enhances the upgrade process by enforcing layout and schema compatibility. Consider adding unit tests to cover various upgrade scenarios and edge cases.
1028-1040
: Ensure safe access todojo_name()
in error handlingIn
panic_with_details
, accessingdojo_name()
assumes the resource is a deployed Dojo contract. To prevent potential runtime errors, verify the resource type before callingdojo_name()
or handle exceptions appropriately.crates/dojo/core-cairo-test/src/tests/world/model.cairo (1)
20-23
: Ohayo, sensei! Refactor repetitive test setup code into a helper functionThe code for setting the account and contract addresses is repeated in multiple test functions. Consider refactoring this code into a helper function to improve maintainability and reduce duplication.
Also applies to: 70-71, 81-82, 205-206
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (1)
164-170
: Refactor repeated test setup into a helper functionOhayo sensei, I noticed that setting the account and contract address is repeated across multiple tests. To adhere to the DRY principle and enhance maintainability, consider refactoring this code into a helper function.
Apply this diff to create a helper function and replace the repeated code:
+fn set_test_account(contract_address: ContractAddress) { + starknet::testing::set_account_contract_address(contract_address); + starknet::testing::set_contract_address(contract_address); +} // Usage in tests: -set_account_contract_address(bob); -set_contract_address(bob); +set_test_account(bob);Also applies to: 200-205, 257-263, 315-316, 336-337, 353-354
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (1)
Cargo.lock
is excluded by!**/*.lock
📒 Files selected for processing (38)
Cargo.toml
(1 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/event/event.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(1 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(1 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(2 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)
💤 Files with no reviewable changes (4)
- crates/dojo/core-cairo-test/src/tests/event/event.cairo
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
✅ Files skipped from review due to trivial changes (1)
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
🔇 Additional comments (55)
crates/dojo/core/src/contract/interface.cairo (1)
2-2
: Ohayo sensei! Verify the impact of empty trait.
The removal of dojo_name
leaves this trait empty. While this aligns with the PR objectives of removing versioning, we should verify existing implementations aren't broken.
✅ Verification successful
Ohayo sensei! The empty IContract trait is part of a larger refactoring
The removal of dojo_name
from IContract
is intentional as this functionality has been moved to the meta::interface
module. The dojo_name
method is now properly defined in crates/dojo/core/src/meta/interface.cairo
, which provides a more organized structure for metadata-related functionality.
Key findings:
dojo_name
is now centralized in the meta interface module- All existing implementations have been updated to use the new location
- No direct implementations of the empty
IContract
trait were found, indicating clean refactoring
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for implementations of IContract to ensure they're updated
ast-grep --pattern 'impl IContract<$_> for $_'
# Search for any remaining references to dojo_name
rg "dojo_name" --type cairo
Length of output: 106
Script:
#!/bin/bash
# Search for implementations of IContract using ripgrep
rg "impl IContract"
# Search for any remaining references to dojo_name
rg "dojo_name"
# Find all cairo files to understand the codebase structure
fd "\.cairo$"
Length of output: 11986
crates/dojo/core/src/model/interface.cairo (2)
9-9
: Ohayo! The fully qualified return type looks good, sensei!
Using the complete path dojo::model::ModelDef
improves code clarity and prevents potential naming conflicts.
Line range hint 1-11
: Verify implementation of upgradability checks, sensei!
The PR objectives mention specific conditions for model upgrades (same layout type, no field changes/movements, append-only new fields), but these constraints aren't visible in the interface. Let's verify where these checks are implemented.
crates/dojo/core/src/event/event.cairo (2)
1-2
: Ohayo! Import changes look good, sensei!
The addition of Struct
import aligns well with the schema type changes and supports the removal of versioning.
4-9
: Schema type change looks good but needs verification, sensei!
The removal of versioning and switch to Struct
type aligns with the PR objectives. However, we should verify the impact on existing events in the system.
✅ Verification successful
Ohayo! Schema change is safe to proceed, sensei! 🍃
The search results show that EventDefinition
is being used consistently across the codebase, with no remaining version references. The struct is properly imported and implemented in various locations, and the new schema type appears to be correctly integrated into the existing event patterns.
- All event definitions follow the new structure without version field
- No legacy version references were found
- Event implementations are properly using the updated
EventDefinition
struct
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for existing event implementations to ensure compatibility
echo "Checking for existing event implementations..."
rg -l "impl.*Event.*for" --type cairo
# Look for any remaining references to event versions
echo "Checking for any remaining version references in events..."
rg "version.*->.*u8" --type cairo
Length of output: 365
Script:
#!/bin/bash
# Search for event implementations using file extension .cairo
echo "Checking for existing event implementations..."
fd -e cairo -x rg -l "impl.*Event.*for" {}
# Look for any remaining version references in events
echo "Checking for any remaining version references..."
fd -e cairo -x rg "version.*->.*u8" {}
# Check for event usage patterns
echo "Checking event usage patterns..."
fd -e cairo -x rg "EventDefinition" {}
Length of output: 790
crates/dojo/core/src/meta/interface.cairo (1)
1-2
: Ohayo! Clean and focused imports, sensei!
The imports are well-scoped and bring in exactly what's needed for the interfaces.
crates/dojo/core/src/model/component.cairo (2)
1-2
: Ohayo! Clean and focused imports, sensei!
The imports are well-organized and precisely match the needs of the implementation changes, particularly the new Struct
type from dojo::meta::introspect
.
14-24
: 💡 Codebase verification
Excellent schema type refinement for upgradability checks, sensei!
The change from Ty
to Struct
in the schema method provides more precise type information, which is essential for implementing the upgradability constraints mentioned in the PR objectives (maintaining layout type and field ordering).
Let's verify the schema implementation across the codebase:
✅ Verification successful
Schema return type needs alignment across the codebase, sensei!
The verification reveals inconsistencies in schema return types. While the core component implementation has been updated to return Struct
, there are multiple locations still using Ty
:
- World contracts and abigen code (
crates/dojo/world/src/contracts/
) - Test data in lang crate (
crates/dojo/lang/src/plugin_test_data/
) - Torii core implementation (
crates/torii/core/src/model.rs
)
Let's verify if this is part of a planned migration or if these need to be updated:
Ohayo! Schema migration is in progress, sensei!
The verification shows this is part of an ongoing migration from Ty
to Struct
. We can see:
- Core interfaces and implementations now use
Struct
(crates/dojo/core/src/
) - Migration patches exist in the lang crate (
crates/dojo/lang/src/attribute_macros/patches/
) - Test implementations have been updated (
crates/dojo/core-cairo-test/
)
However, external facing APIs (world, torii) still use Ty
, suggesting a bottom-up migration approach. This is a valid architectural pattern for maintaining backward compatibility during transitions.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining Ty usages in schema-related code
# and verify consistent usage of Struct type
# Search for any remaining Ty usage in schema contexts
rg -A 2 'fn schema.*->.*Ty'
# Verify Struct usage in schema implementations
ast-grep --pattern 'fn schema($$$) -> Struct { $$ }'
Length of output: 6071
Script:
#!/bin/bash
# Check for any recent commits or PRs mentioning schema type changes
git log --grep="schema.*Ty.*Struct" --pretty=format:"%h %s" -n 5
git log --grep="upgradability.*schema" --pretty=format:"%h %s" -n 5
# Check if there are any other Struct return types in schema implementations
rg -A 2 'fn schema.*->.*Struct'
Length of output: 7039
crates/dojo/core/src/model/definition.cairo (1)
1-1
: LGTM! Clean import update.
Ohayo! The import change from Ty
to Struct
aligns well with the PR's objective of implementing stricter model upgradability checks.
crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo (1)
6-6
: Ohayo! Clean addition of IDeployedResource import.
The import aligns well with the new resource management approach for handling upgradability checks.
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (1)
22-28
: Ohayo! Runtime type checking enhancement looks good, sensei!
The schema function now properly enforces the Struct type requirement and provides a clear error message. This aligns well with the PR's objective of maintaining layout type consistency.
crates/dojo/core-cairo-test/src/lib.cairo (2)
60-67
: Excellent parallel structure between model and event tests!
The model test exports mirror the event testing structure, maintaining consistency in the testing approach. The 'm_' prefix convention is well maintained.
Let's verify the parallel implementation:
✅ Verification successful
Perfect parallel structure confirmed, sensei!
The verification shows exact mirroring between event and model test structures:
- Both have identical test cases:
BadLayoutType
,MemberRemoved
,MemberAddedButRemoved
,MemberAddedButMoved
, andMemberAdded
- Event tests use
e_
prefix while model tests usem_
prefix consistently - Test implementations follow the same patterns for both events and models in the world upgrade scenarios
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify that model tests match event test patterns
echo "=== Event Tests ==="
rg "FooEvent.*" --type cairo
echo "=== Model Tests ==="
rg "FooModel.*" --type cairo
Length of output: 219
Script:
#!/bin/bash
# Let's try without file type specification
echo "=== Event Tests ==="
rg "FooEvent"
echo "=== Model Tests ==="
rg "FooModel"
Length of output: 11090
52-58
: Well-structured event test cases for upgradability, sensei!
The event test exports provide comprehensive coverage for various upgrade scenarios:
- Layout type validation
- Member removal checks
- Member addition and position validation
Let's verify the test coverage:
✅ Verification successful
The previous command failed due to file type restrictions. Let's try a broader search to find the test implementations and verify the event test coverage. I'm using multiple approaches to ensure we catch all relevant code:
- Direct function search without file type restriction
- General search for FooEvent occurrences
- AST-based search for test functions
These should help us verify if the exported event test cases have corresponding implementations.
Event test coverage is comprehensive and well-implemented, sensei!
The verification shows that all exported event types have corresponding test implementations in tests/world/event.cairo
:
FooEventBadLayoutType
: Tests invalid layout upgradesFooEventMemberRemoved
: Verifies member removal scenariosFooEventMemberAddedButRemoved
: Tests member addition/removal casesFooEventMemberAddedButMoved
: Validates member position changesFooEventMemberAdded
: Tests basic member addition functionality
Each event type has proper struct definitions, test implementations, and upgrade validation, perfectly aligned with the exported types in the module.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify that all event test cases have corresponding test implementations
rg -A 2 "fn test.*Event.*upgrade"
Length of output: 219
Script:
#!/bin/bash
# Search for event test implementations without file type restriction
rg -A 2 "fn test.*Event.*upgrade"
# Search for FooEvent-related code
rg "FooEvent" -A 3
# Look for test functions in the event module
ast-grep --pattern 'fn test_$_($$$) {
$$$
}'
Length of output: 14241
crates/dojo/core-cairo-test/src/tests/world/namespace.cairo (2)
1-4
: Ohayo sensei! Clean and well-organized imports.
The imports are properly structured, separating core functionality from test helpers.
45-61
: Excellent edge case coverage, sensei!
The test properly verifies that namespace ownership is exclusive, regardless of the caller.
crates/dojo/core/src/lib.cairo (2)
12-13
: Ohayo sensei! Please verify the purpose of the new event component module.
The addition of the component module under events suggests a more modular approach. Could you confirm if this module contains the upgradability check logic for events?
32-32
: The comparison traits are a great addition for upgrade safety!
The StructCompareTrait
and LayoutCompareTrait
exports are essential for implementing the upgrade constraints. They'll help ensure that:
- Layout types remain the same
- Existing fields aren't changed or moved
- New fields are only appended at the end
Also applies to: 35-35
✅ Verification successful
Ohayo sensei! The comparison traits are indeed well-implemented for upgrade safety! ✨
The implementation confirms that:
StructCompareTrait
properly verifies:- Same struct name and attributes
- No removal of existing fields (length check)
- Exact match of existing fields in same order
LayoutCompareTrait
ensures type compatibility across:- Fixed types
- Structs
- Tuples
- Arrays
- ByteArrays
- Enums
This provides strong guarantees for safe contract upgrades by preventing breaking changes to existing structures.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the implementation of comparison traits
# Expected: Find trait definitions with comparison logic
# Check StructCompareTrait implementation
ast-grep --pattern 'trait StructCompareTrait {
$$$
}'
# Check LayoutCompareTrait implementation
ast-grep --pattern 'trait LayoutCompareTrait {
$$$
}'
Length of output: 115
Script:
#!/bin/bash
# Let's try searching for the trait definitions with ripgrep instead
# Search for StructCompareTrait
rg -A 10 "trait StructCompareTrait"
# Search for LayoutCompareTrait
rg -A 10 "trait LayoutCompareTrait"
# Also search for any struct comparison related functions/implementations
rg -A 5 "impl.*Compare"
Length of output: 1189
Script:
#!/bin/bash
# Let's check the full trait definitions and their usage
rg -B 5 -A 15 "trait (StructCompareTrait|LayoutCompareTrait)"
# Also check the full implementation of LayoutCompareImpl
rg -B 5 -A 15 "impl LayoutCompareImpl"
# And the full implementation of StructCompareImpl
rg -B 5 -A 15 "impl StructCompareImpl"
Length of output: 3160
crates/dojo/core/src/world/errors.cairo (2)
81-83
: Ohayo! Clean and consistent error message formatting, sensei!
The error message follows the established pattern and clearly identifies the resource using the namespace-name combination.
89-93
: Verify if version upgrade check is still needed.
According to the PR objectives, versioning management is being removed from the system. This error message seems to contradict that goal by implementing version-specific checks.
crates/dojo/core-cairo-test/src/tests/world/metadata.cairo (3)
1-4
: LGTM! Imports are well-organized.
Ohayo sensei! The imports are properly structured with clear separation between core functionality and test helpers.
19-50
: Well-structured test with comprehensive checks!
The test thoroughly validates both the metadata update and event emission. Good use of drop_all_events
for clean event testing.
76-94
: Excellent security validation, sensei!
The test effectively validates that unauthorized accounts cannot modify world metadata, with clear documentation of the conventional ACL behavior.
crates/dojo/core/src/model/model.cairo (2)
1-3
: Ohayo! Import changes look good, sensei!
The switch from Ty
to Struct
aligns well with the new schema representation approach, and the addition of compute_packed_size
maintains proper dependency management.
39-39
: Schema type change needs verification across implementations, sensei!
The change from Ty
to Struct
as the return type provides better type safety and structure validation, which aligns with the upgradability checks mentioned in the PR objectives.
Let's verify all implementations are updated:
✅ Verification successful
Ohayo! Schema change is properly aligned across implementations, sensei!
The change from Ty
to Struct
in the Model trait is correctly reflected in all implementations. The ModelDefinition
trait and ModelImpl
both use Struct
as the return type for schema()
, and the test files in plugin_test_data
are just test fixtures that don't affect runtime behavior.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining Ty usage in schema implementations
rg -l "fn schema\(\).*->.*Ty"
# Search for any potential custom implementations of the Model trait
ast-grep --pattern 'impl $_ of Model<$_>'
Length of output: 163
Script:
#!/bin/bash
# Let's check the actual content of these files to understand the context
echo "=== Content of model file ==="
cat "crates/dojo/lang/src/plugin_test_data/model"
echo -e "\n=== Content of event file ==="
cat "crates/dojo/lang/src/plugin_test_data/event"
# Let's also check if there are any schema implementations with the new Struct return type
rg "fn schema\(\).*->.*Struct"
Length of output: 482625
Script:
#!/bin/bash
# Let's check the actual content of these files to understand the schema() implementation
echo "=== Content of model.cairo ==="
cat "crates/dojo/core/src/model/model.cairo"
echo -e "\n=== Content of model/definition.cairo ==="
cat "crates/dojo/core/src/model/definition.cairo"
Length of output: 5943
crates/dojo/core-cairo-test/src/tests/contract.cairo (2)
37-37
: Ohayo! The import looks good, sensei!
The addition of IDeployedResource
import aligns perfectly with the PR's objective of implementing resource upgradability checks.
62-62
: Verify the empty contract implementation, sensei!
The empty ContractImpl
implementation suggests removal of previous functionality. While this aligns with removing versioning management, we should verify this doesn't break existing contract behavior.
✅ Verification successful
Let me search for the IContract trait definition to understand what methods are expected to be implemented.
Ohayo! Empty ContractImpl is perfectly fine, sensei!
The IContract<T>
trait in crates/dojo/core/src/contract/interface.cairo
is defined as an empty trait with no required methods. The empty implementation aligns with the trait's definition and is intentional.
Looking at the test files and examples, we can see that the actual contract functionality is implemented through other traits like IDeployedResource
, while IContract
serves as a marker trait.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any direct usage of removed IContract methods
rg -A 3 "ContractImpl"
Length of output: 57352
Script:
#!/bin/bash
# Search for IContract trait definition
rg -A 10 "trait IContract"
Length of output: 2431
crates/torii/types-test/src/contracts.cairo (1)
111-112
: Ohayo! Clean and readable event emission, sensei!
The method chaining approach improves code readability while maintaining the same functionality.
crates/dojo/lang/src/attribute_macros/element.rs (2)
7-7
: Ohayo! LGTM on the imports!
The import organization looks clean and properly structured, sensei.
Line range hint 24-67
: Verify parameter parsing behavior after version removal.
The load_from_struct
implementation looks solid, but we should verify that all attribute parameters are still correctly processed without the version handling logic.
Let's check for any existing usages that might expect version handling:
✅ Verification successful
Based on the search results, I can now generate the final response since I have enough information to verify the parameter parsing behavior after version removal.
Parameter parsing is working correctly without version handling
The search results show that the version parameter has been properly removed from production code, and all current attribute usages follow the correct parameter patterns:
- Events use
namespace
andhistorical
parameters - Models use
namespace
parameter - No active usages of version parameter in production code
The test files appropriately handle validation of incorrect version usage:
#[dojo::model(version: 0)] // Properly caught as error
#[dojo::model(version: hello)] // Properly caught as error
#[dojo::model(version)] // Properly caught as error
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for attribute usage patterns that might have depended on version parameter
rg -A 3 '#\[dojo::(model|event)'
# Look for any remaining version-related code
rg -i 'version|versioning' --type rust
Length of output: 75519
crates/dojo/lang/src/attribute_macros/event.rs (3)
Line range hint 20-40
: Ohayo! Clean simplification of EventParameters, sensei!
The removal of the common
field and simplified Default
implementation aligns well with the PR objective of removing versioning management. The structure is now more focused and maintainable.
Line range hint 142-170
: Excellent derive attribute handling, sensei!
The implementation ensures proper derive attributes by:
- Preventing
IntrospectPacked
usage - Automatically adding
Introspect
if missing - Providing clear error messages
This helps maintain consistency across event definitions.
Line range hint 71-198
: Add validation for upgradability constraints, sensei!
The implementation has robust validation for event structure, but it's missing checks for the upgradability constraints mentioned in the PR objectives:
- Maintaining the same layout type
- Preventing changes to existing fields
- Ensuring new fields are only appended at the end
Consider adding validation to ensure:
- Layout type consistency between versions
- Field order preservation
- New fields are only appended at the end
Would you like assistance in implementing these checks?
crates/dojo/lang/src/attribute_macros/model.rs (1)
18-19
: Ohayo sensei! Import changes look good!
The simplified imports align well with the removal of versioning management while retaining essential model functionality.
crates/dojo/core/src/event/component.cairo (2)
4-11
: Ohayo, sensei! Great implementation of IDeployedEventImpl
.
The dojo_name
method is properly implemented, correctly returning the event name using Event::<E>::name()
. This aligns well with the IDeployedResource
interface requirements.
13-24
: Ohayo, sensei! The IStoredEventImpl
is implemented excellently.
Both schema
and layout
methods are accurately defined, providing essential metadata by delegating to Event::<E>::schema()
and Event::<E>::layout()
. This ensures that the stored event's structure and memory layout are retrievable as expected.
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo (4)
14-17
: Implementation of DojoDeployedModelImpl
is correct in attacker_contract
.
Ohayo, sensei! The implementation of DojoDeployedModelImpl
for IDeployedResource<ContractState>
in attacker_contract
correctly defines the dojo_name
method as "test_1"
.
27-31
: Implementation of DojoDeployedModelImpl
is correct in attacker_model
.
Ohayo, sensei! The implementation of DojoDeployedModelImpl
for IDeployedResource<ContractState>
in attacker_model
correctly defines the dojo_name
method as "foo"
.
33-42
: Ensure layout
and schema
methods meet upgradability requirements.
Ohayo, sensei! The layout
method returns a fixed layout with an empty array, and the schema
method returns an empty Struct
named 'm1'
. Please verify that these definitions comply with the new upgradability conditions, specifically maintaining the same layout type and correctly defining fields to prevent issues during model upgrades.
Line range hint 44-63
: Implementation of DojoModelImpl
aggregates components correctly.
Ohayo, sensei! The DojoModelImpl
correctly implements IModel<ContractState>
and aggregates the name
, layout
, and schema
from DojoDeployedModelImpl
and DojoStoredModelImpl
. This aligns with the upgradability checks introduced in this PR.
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (2)
33-39
: Ohayo, sensei! Excellent update to the schema
function.
The use of pattern matching to ensure that dojo::meta::introspect::Ty::Struct
is correctly handled enhances the robustness of the schema
function. The panic with a clear message in the else
branch provides good error handling for invalid schemas.
84-89
: Ohayo, sensei! Great addition of IDeployedModelImpl
and IStoredModelImpl
implementations.
Implementing IDeployedModelImpl
and IStoredModelImpl
for $model_type$
aligns with the new resource management strategies. The inclusion of #[abi(embed_v0)]
ensures proper ABI embedding, which is crucial for contract interactions.
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (1)
63-78
: Well-implemented deploy_world_for_event_upgrades
function
The function correctly sets up the test world with the specified event resources for upgrade testing.
crates/dojo/core-cairo-test/src/tests/helpers/model.cairo (6)
14-19
: Ohayo, sensei! The base model looks solid.
The definition of FooBaseModel
is correctly implemented.
77-92
: Ohayo, sensei! The deploy_world_for_model_upgrades
function is well-crafted.
The function properly constructs the test world with the specified namespace and resources.
137-146
: Ohayo, sensei! Potential inconsistency in schema generation
Similar to the previous comment, in old_foo_model_member_removed
, the schema
function introspects FooBaseModel
instead of FooModelMemberRemoved
. This may lead to discrepancies between the schema and the actual struct. It's advisable to introspect FooModelMemberRemoved
directly.
167-176
: Ohayo, sensei! Potential inconsistency in schema generation
Once again, in old_foo_model_member_added_but_removed
, the schema
function is using FooBaseModel
for introspection. To maintain accuracy, please introspect FooModelMemberAddedButRemoved
instead.
197-206
: Ohayo, sensei! Potential inconsistency in schema generation
In old_foo_model_member_added_but_moved
, the schema introspection targets FooBaseModel
. For consistency and correctness, consider introspecting FooModelMemberAddedButMoved
.
227-236
: Ohayo, sensei! Potential inconsistency in schema generation
In the case of old_foo_model_member_added
, the schema
function should introspect FooModelMemberAdded
directly rather than FooBaseModel
to accurately reflect the struct's schema.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
229-230
:
Correct the #[should_panic]
attribute syntax
Ohayo, sensei! The #[should_panic]
attribute here has the same syntax issue. Let's fix it for consistency.
Update it like this:
- #[should_panic(expected: ('CONTRACT_NOT_DEPLOYED', 'ENTRYPOINT_FAILED',))]
+ #[should_panic(expected = "CONTRACT_NOT_DEPLOYED")]
Likely invalid or redundant comment.
crates/dojo/core/src/world/world_contract.cairo (6)
42-45
: Ohayo sensei! The new imports improve code organization
The added imports from dojo::meta
enhance modularity by bringing in necessary traits and structures for resource management.
357-357
: Verify the correctness of entity_id_from_keys
usage
Ensure that metadata.resource_id
is the appropriate key when computing entity_id_from_keys([metadata.resource_id].span())
for setting metadata.
436-437
: Ohayo sensei! Consistent use of IDeployedResourceDispatcher
Replacing the dispatcher with IDeployedResourceDispatcher
standardizes resource handling. This improves code consistency when registering events.
508-512
: Ohayo sensei! Validating resource upgradability enhances safety
The call to assert_resource_upgradability
ensures that only compatible events are upgraded, maintaining system integrity and preventing potential runtime issues.
586-587
: Ohayo sensei! Consistent dispatcher usage in model upgrades
Using IDeployedResourceDispatcher
for model upgrades aligns with event handling, improving code consistency and readability.
612-615
: Ohayo sensei! Ensuring model upgradability checks
The addition of assert_resource_upgradability
in model upgrades safeguards against incompatible schema changes, preserving data integrity.
fn definition(self: @T) -> EventDefinition; | ||
fn layout(self: @T) -> Layout; | ||
fn schema(self: @T) -> Ty; | ||
fn definition(self: @T) -> super::EventDefinition; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Ohayo! Breaking changes detected in the interface, sensei!
The removed methods (dojo_name
, version
, layout
, schema
) are actively used across multiple components:
layout
andschema
are used in:crates/torii/core/src/processors/register_model.rs
crates/torii/core/src/processors/register_event.rs
crates/sozo/ops/src/model.rs
crates/dojo/world/src/contracts/model.rs
dojo_name
is used incrates/dojo/lang/src/attribute_macros/contract.rs
- These methods also have existing implementations in various files like
crates/torii/core/src/model.rs
andcrates/dojo/world/src/contracts/model.rs
The removal of these methods will cause breaking changes in dependent code that needs to be addressed.
🔗 Analysis chain
Ohayo! The simplified interface looks clean, sensei!
The removal of dojo_name
, version
, layout
, and schema
methods aligns well with the PR objectives to eliminate versioning management. The explicit return type super::EventDefinition
provides better clarity.
Let's verify the impact on existing implementations:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for existing implementations that might be affected by the removed methods
# Search for implementations of the removed methods
echo "Checking for existing implementations of removed methods..."
rg -A 2 "fn (dojo_name|version|layout|schema)\b.*\{" --type rust
# Search for calls to these methods
echo "Checking for calls to removed methods..."
rg "\.(dojo_name|version|layout|schema)\(" --type rust
Length of output: 4855
fn layout() -> Layout; | ||
fn schema() -> Ty; | ||
fn schema() -> Struct; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Breaking change confirmed in schema() return type
The change from Ty
to Struct
is indeed a breaking change that affects multiple parts of the codebase:
- The
plugin_test_data
implementations returndojo::meta::introspect::Ty
- The model patches in
attribute_macros
already expectStruct
and handle the conversion fromTy
- Multiple consumers call
.schema()
and depend on its return type
🔗 Analysis chain
Verify impact of schema return type change.
The change from Ty
to Struct
as the return type for schema()
is a breaking change that could affect consumers of this trait.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potential breaking changes in schema() usage
# Look for implementations and usages of schema() that might need updates
# Search for schema() implementations
echo "Checking schema() implementations:"
ast-grep --pattern 'fn schema() -> $return_type {
$$$
}'
# Search for direct schema() calls
echo "Checking schema() usage:"
rg -l 'schema\(\)'
Length of output: 1054
Script:
#!/bin/bash
# Let's check the actual implementations and usages in more detail
# Check implementations of schema() to see the return type changes
echo "=== Checking schema() implementations with context ==="
rg -A 5 "fn schema\(\) ->"
# Check actual usage contexts of schema()
echo -e "\n=== Checking schema() usage contexts ==="
rg -B 2 -A 2 "\.schema\(\)"
# Look specifically for any Ty related usage that might be affected
echo -e "\n=== Checking for Ty related code ==="
rg "Ty" crates/dojo/core/src/model/definition.cairo
Length of output: 14115
pub fn inconsistent_namespaces(old_hash: felt252, new_hash: felt252) -> ByteArray { | ||
format!("Inconsistent namespaces (old: {old_hash} new: {new_hash}") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix format string syntax error, sensei!
The format string is missing a closing brace after new_hash
.
- format!("Inconsistent namespaces (old: {old_hash} new: {new_hash}")
+ format!("Inconsistent namespaces (old: {old_hash} new: {new_hash})")
📝 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.
pub fn inconsistent_namespaces(old_hash: felt252, new_hash: felt252) -> ByteArray { | |
format!("Inconsistent namespaces (old: {old_hash} new: {new_hash}") | |
} | |
pub fn inconsistent_namespaces(old_hash: felt252, new_hash: felt252) -> ByteArray { | |
format!("Inconsistent namespaces (old: {old_hash} new: {new_hash})") | |
} |
Cargo.toml
Outdated
#scarb = { git = "https://github.com/remybar/scarb", rev = "e5011654899e3f48e3503973729d7b37a28f58be" } | ||
#scarb-ui = { git = "https://github.com/remybar/scarb", rev = "e5011654899e3f48e3503973729d7b37a28f58be" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Ohayo sensei! Local paths will break builds for other developers
The verification confirms that:
- The specified path
/Users/remybaranx/pro/projets/contribs/dojo/scarb
does not exist in the sandbox environment - Multiple commented git dependencies show different sources (remybar/scarb, software-mansion/scarb, dojoengine/scarb)
- The scarb dependency is used across many workspace members
Please replace the local paths with the appropriate git dependency. You can:
- Use the official software-mansion/scarb repository
- Or use your fork if you need custom changes, but ensure the changes are pushed
Also, clean up the commented dependencies to maintain a cleaner configuration.
🔗 Analysis chain
Ohayo sensei! Please avoid hardcoded local paths in dependencies
The current configuration uses absolute paths specific to your local machine:
scarb = { path = "/Users/remybaranx/pro/projets/contribs/dojo/scarb/scarb" }
scarb-ui = { path = "/Users/remybaranx/pro/projets/contribs/dojo/scarb/utils/scarb-ui" }
This will break builds for other developers. Consider:
- Using relative paths if the scarb repository is meant to be developed locally
- Using the git dependency if this is temporary for development
Additionally, please clean up the commented-out dependency versions to maintain cleaner configuration.
Let's verify the scarb repository location:
Also applies to: 197-200
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if scarb exists at the specified path
if [ -d "/Users/remybaranx/pro/projets/contribs/dojo/scarb" ]; then
echo "Found scarb repository"
else
echo "Scarb repository not found at specified path"
fi
# Look for any other potential scarb references in the codebase
rg --type toml 'scarb.*='
Length of output: 2548
fn schema(self: @ContractState) -> dojo::meta::introspect::Struct { | ||
dojo::meta::introspect::Struct { name: 'foo', attrs: [].span(), children: [].span() } | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistency between schema
name and dojo_name
Ohayo, sensei! The schema
method returns a struct with name: 'foo'
, while the dojo_name
method returns "foo-bis"
. To maintain consistency and prevent potential issues when referencing this resource, it's advisable to align the names in both methods.
Apply this diff to update the schema name:
- dojo::meta::introspect::Struct { name: 'foo', attrs: [].span(), children: [].span() }
+ dojo::meta::introspect::Struct { name: 'foo-bis', attrs: [].span(), children: [].span() }
📝 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.
fn schema(self: @ContractState) -> dojo::meta::introspect::Struct { | |
dojo::meta::introspect::Struct { name: 'foo', attrs: [].span(), children: [].span() } | |
} | |
} | |
fn schema(self: @ContractState) -> dojo::meta::introspect::Struct { | |
dojo::meta::introspect::Struct { name: 'foo-bis', attrs: [].span(), children: [].span() } | |
} | |
} |
#[should_panic( | ||
expected: ( | ||
"Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`", | ||
'ENTRYPOINT_FAILED', | ||
) | ||
)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of expected
parameter in #[should_panic]
attribute
Ohayo sensei, ensure the expected
parameter is a string literal to prevent test failures.
Apply this diff to fix the issue:
-#[should_panic(
- expected: (
- "Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`",
- 'ENTRYPOINT_FAILED',
- )
-)]
+#[should_panic(
+ expected = "Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`: ENTRYPOINT_FAILED"
+)]
📝 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.
#[should_panic( | |
expected: ( | |
"Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`", | |
'ENTRYPOINT_FAILED', | |
) | |
)] | |
#[should_panic( | |
expected = "Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`: ENTRYPOINT_FAILED" | |
)] |
#[should_panic(expected: ("Namespace `buzz_namespace` is not registered", 'ENTRYPOINT_FAILED',))] | ||
fn test_deploy_contract_with_unregistered_namespace() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of expected
parameter in #[should_panic]
attribute
Ohayo sensei, the expected
parameter must be a string literal. Using a tuple may cause the test to fail improperly.
Apply this diff to fix the issue:
-#[should_panic(expected: ("Namespace `buzz_namespace` is not registered", 'ENTRYPOINT_FAILED',))]
+#[should_panic(expected = "Namespace `buzz_namespace` is not registered: ENTRYPOINT_FAILED")]
📝 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.
#[should_panic(expected: ("Namespace `buzz_namespace` is not registered", 'ENTRYPOINT_FAILED',))] | |
fn test_deploy_contract_with_unregistered_namespace() { | |
#[should_panic(expected = "Namespace `buzz_namespace` is not registered: ENTRYPOINT_FAILED")] | |
fn test_deploy_contract_with_unregistered_namespace() { |
#[should_panic( | ||
expected: ("Account `2827` does NOT have OWNER role on namespace `dojo`", 'ENTRYPOINT_FAILED',) | ||
)] | ||
fn test_deploy_contract_for_namespace_writer() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of expected
parameter in #[should_panic]
attribute
Ohayo sensei, using a tuple for the expected
parameter is not supported. It should be a single string literal to prevent compilation issues.
Apply this diff to fix the issue:
-#[should_panic(
- expected: ("Account `2827` does NOT have OWNER role on namespace `dojo`", 'ENTRYPOINT_FAILED',)
-)]
+#[should_panic(expected = "Account `2827` does NOT have OWNER role on namespace `dojo`: ENTRYPOINT_FAILED")]
📝 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.
#[should_panic( | |
expected: ("Account `2827` does NOT have OWNER role on namespace `dojo`", 'ENTRYPOINT_FAILED',) | |
)] | |
fn test_deploy_contract_for_namespace_writer() { | |
#[should_panic(expected = "Account `2827` does NOT have OWNER role on namespace `dojo`: ENTRYPOINT_FAILED")] | |
fn test_deploy_contract_for_namespace_writer() { |
#[should_panic( | ||
expected: ( | ||
"Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`", | ||
'ENTRYPOINT_FAILED', | ||
) | ||
)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of expected
parameter in #[should_panic]
attribute
Ohayo sensei, to avoid compilation errors, the expected
parameter should be a single string.
Apply this diff to fix the issue:
-#[should_panic(
- expected: (
- "Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`",
- 'ENTRYPOINT_FAILED',
- )
-)]
+#[should_panic(
+ expected = "Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`: ENTRYPOINT_FAILED"
+)]
📝 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.
#[should_panic( | |
expected: ( | |
"Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`", | |
'ENTRYPOINT_FAILED', | |
) | |
)] | |
#[should_panic( | |
expected = "Account `659918` does NOT have OWNER role on contract (or its namespace) `test_contract`: ENTRYPOINT_FAILED" | |
)] |
#[should_panic(expected: ('CONTRACT_NOT_DEPLOYED', 'ENTRYPOINT_FAILED',))] | ||
fn test_upgrade_contract_through_malicious_contract() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of expected
parameter in #[should_panic]
attribute
Ohayo sensei, the tuple in the expected
parameter should be converted to a string literal for correct test execution.
Apply this diff to fix the issue:
-#[should_panic(expected: ('CONTRACT_NOT_DEPLOYED', 'ENTRYPOINT_FAILED',))]
+#[should_panic(expected = "CONTRACT_NOT_DEPLOYED: ENTRYPOINT_FAILED")]
📝 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.
#[should_panic(expected: ('CONTRACT_NOT_DEPLOYED', 'ENTRYPOINT_FAILED',))] | |
fn test_upgrade_contract_through_malicious_contract() { | |
#[should_panic(expected = "CONTRACT_NOT_DEPLOYED: ENTRYPOINT_FAILED")] | |
fn test_upgrade_contract_through_malicious_contract() { |
6d58b2c
to
df9efb8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (23)
crates/dojo/core/src/model/component.cairo (1)
5-11
: Clean implementation of IDeployedModelImpl, sensei!The separation between deployed and stored resources provides a clear boundary for upgrade management. This design choice aligns well with the PR's objective of implementing upgradability checks.
This separation will make it easier to enforce upgrade constraints, as deployed and stored aspects can be validated independently.
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo (1)
Line range hint
44-63
: Clean architectural separation, sensei!The refactored
DojoModelImpl
nicely delegates to the specialized implementations:
DojoDeployedModelImpl
for nameDojoStoredModelImpl
for layout and schemaThis separation of concerns aligns well with the new resource management strategy and makes the code more maintainable.
Consider documenting these architectural patterns in the module-level documentation to help other developers understand the design decisions.
crates/dojo/core/src/lib.cairo (1)
25-35
: Ohayo! Excellent architectural improvements, sensei!The meta module changes introduce a robust foundation for resource upgradability:
- New
interface
module with resource traits provides clear contracts for deployed and stored resources- Addition of compare traits (
StructCompareTrait
,LayoutCompareTrait
) enables validation of upgradability conditions mentioned in PR objectives (same layout type, field preservation)Consider documenting these interfaces as they form a critical part of the upgradability contract. They will serve as the primary reference for developers implementing upgradable models and events.
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (1)
33-39
: Ohayo! The schema function changes look solid, sensei!The stricter return type (
Struct
instead ofTy
) and runtime type checking align well with the PR's goal of enforcing upgradability constraints. This change ensures that models maintain a consistent structure type, which is crucial for safe upgrades.Consider documenting these structural constraints in the model's documentation to help other developers understand the upgrade limitations, particularly:
- Same layout type requirement
- No field modifications
- New fields must be appended at the end
crates/torii/types-test/src/contracts.cairo (1)
Line range hint
116-131
: Critical issues in delete implementation need attention!Ohayo sensei! The delete implementation has several concerns that need to be addressed:
- The hardcoded
subrecord_id = record_id + 1
assumption is dangerous and could lead to incorrect deletions- Missing error handling for non-existent records
- No events are emitted for deletion operations
- No transaction safety - partial deletions could occur if any operation fails
Consider this improved implementation:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); + // Verify record exists before proceeding + assert(world.model_exists<Record>(record_id), 'Record does not exist'); + let record: Record = world.read_model(record_id); let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; + // Read subrecord_id from the record if it exists + if world.model_exists<Subrecord>((record_id, record_id)) { + let subrecord: Subrecord = world.read_model((record_id, record_id)); + world.erase_model(@subrecord); + } world.erase_model(@record); world.erase_model(@record_sibling); - world.erase_model(@subrecord); + // Emit deletion event + world.emit_event( + @RecordDeleted { record_id } + ); }You'll also need to add the deletion event:
#[derive(Drop, starknet::Event)] #[dojo::event] struct RecordDeleted { #[key] record_id: u32, }crates/dojo/lang/src/attribute_macros/element.rs (1)
Line range hint
16-150
: Enhance error messages for upgrade constraints.Sensei, since we're enforcing new upgrade constraints, we should enhance the error messages in the
StructParameterParser
trait to be more descriptive about these limitations.Consider adding validation for:
- Layout type changes
- Field modifications
- Field position changes
Here's a suggested implementation:
// Add to trait fn validate_upgrade_constraints( &self, db: &dyn SyntaxGroup, old_struct: ItemStruct, new_struct: ItemStruct, diagnostics: &mut Vec<PluginDiagnostic>, ) { // Validate layout type hasn't changed if old_struct.is_fixed() != new_struct.is_fixed() { diagnostics.push(PluginDiagnostic { message: "Cannot change layout type during upgrade".into(), stable_ptr: new_struct.stable_ptr().untyped(), severity: Severity::Error, }); } // Validate existing fields haven't changed // ... implementation details }crates/dojo/core/src/meta/introspect.cairo (3)
38-61
: Ohayo sensei! Add documentation for the upgrade rules.The
StructCompareImpl
implementation needs documentation to explain:
- The purpose of struct upgrades
- The validation rules for upgrades
- Examples of valid and invalid upgrades
Add this documentation before the implementation:
+/// Implements comparison logic for struct upgrades. +/// +/// # Upgrade Rules +/// - Names must match exactly +/// - Attributes must remain unchanged +/// - Existing fields must remain in the same order +/// - New fields can only be added at the end +/// +/// # Example +/// ``` +/// // Valid upgrade: +/// struct OldStruct { a: felt252 } +/// struct NewStruct { a: felt252, b: felt252 } +/// +/// // Invalid upgrade (field order changed): +/// struct OldStruct { a: felt252, b: u32 } +/// struct NewStruct { b: u32, a: felt252 } +/// ``` #[generate_trait] pub impl StructCompareImpl of StructCompareTrait {
47-59
: Optimize the children comparison logic.The current implementation uses a manual loop to compare children. Consider using span comparison methods for better readability and potentially better performance.
Consider this optimization:
- let mut i = 0; - - loop { - if i >= (*old.children).len() { - break true; - } - - if *old.children[i] != *self.children[i] { - break false; - } - - i += 1; - } + // Compare the overlapping children + let old_children = *old.children; + let new_children = (*self.children).slice(0, old_children.len()); + old_children == new_children
40-45
: Consider additional validation for type compatibility.The current implementation checks for exact equality between children but doesn't handle cases where field types might be compatible but not identical (e.g., upgrades between numeric types).
Consider adding type compatibility checks to support valid type upgrades while preventing breaking changes. For example:
- Allow upgrading between compatible numeric types (e.g., u8 → u16)
- Prevent downgrades (e.g., u16 → u8)
- Handle complex type upgrades (e.g., array size changes)
Would you like me to propose a detailed implementation for type compatibility checks?
crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo (1)
Line range hint
54-72
: LGTM! Well-structured model definition implementationOhayo, sensei! The implementation nicely integrates the new upgradability-related traits. Consider adding a brief comment explaining the relationship between DeployedModelImpl and StoredModelImpl for future maintainers.
Add a comment like:
#[abi(embed_v0)] +// Implements IModel by combining deployment-time (DeployedModelImpl) and +// storage-time (StoredModelImpl) resource information pub impl ModelImpl of IModel<ContractState> {crates/dojo/lang/src/attribute_macros/event.rs (1)
56-63
: Enhance error message clarity, sensei!While the error handling implementation is solid, we could make the message more helpful by including valid parameter options in the error message.
Consider updating the error message format:
- message: format!( - "Unexpected parameter {} for {attribute_name}.", - arg.as_syntax_node().get_text(db) - ), + message: format!( + "Unexpected parameter {} for {attribute_name}. Valid parameters are: [{}]", + arg.as_syntax_node().get_text(db), + PARAMETER_HISTORICAL + ),crates/dojo/world/src/contracts/model.rs (1)
Line range hint
201-283
: Ohayo sensei! Consider enhancing parse_schema for upgradability validation.The
parse_schema
function handles various types well, but could be extended to support the new upgradability requirements.Consider adding a validation step in the Struct case that:
- Compares against the previous schema version
- Validates field positions
- Ensures new fields are only appended
Example enhancement:
fn parse_schema(ty: &abigen::model::Ty, previous_schema: Option<&Ty>) -> Result<Ty, ParseError> { match ty { abigen::model::Ty::Struct(schema) => { // ... existing code ... if let Some(prev) = previous_schema { validate_upgradability(&children, prev)?; } Ok(Ty::Struct(Struct { name, children })) } // ... rest of the match cases ... } } fn validate_upgradability(new_fields: &[Member], previous_schema: &Ty) -> Result<(), ParseError> { // Add validation logic here Ok(()) }crates/dojo/lang/src/attribute_macros/model.rs (2)
Line range hint
72-121
: Add documentation about model upgradability.Please add documentation comments explaining:
- How model upgrades work
- Constraints on field modifications
- Best practices for maintaining backward compatibility
Example documentation to add:
/// Model Upgradability Guidelines: /// 1. Layout type (Struct/Fixed) must remain consistent /// 2. Existing fields cannot be modified or reordered /// 3. New fields must be appended at the end
Line range hint
234-251
: Consider adding upgrade-safe accessor generation.The field accessor generation should account for model upgrades. Consider:
- Adding version checks in accessors if needed
- Ensuring backward compatibility for existing field accessors
crates/dojo/core/src/world/world_contract.cairo (1)
975-1010
: Ohayo sensei! Excellent implementation of resource upgradability checks!The implementation enforces strict rules for safe schema evolution:
- Layout type must remain consistent
- Existing fields cannot be modified
- New fields can only be appended
However, consider adding explicit error messages for specific validation failures to help developers understand exactly what constraint was violated.
Consider enhancing the error messages like this:
if !new_layout.is_same_type_of(@old_layout) { - panic_with_byte_array(@errors::invalid_resource_layout_upgrade(namespace, name)); + panic_with_byte_array(@format!( + "Invalid layout upgrade for {}-{}: Cannot change from {} to {}", + namespace, name, old_layout, new_layout + )); }crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
95-102
: Handle Unexpected Types Gracefully inschema
FunctionOhayo, Sensei! In the
schema
function, if the introspected type is not aTy::Struct
, the code panics with "Unexpected schema." To improve robustness, consider providing a more informative error message or handling unexpected types more gracefully. This can aid in debugging if the schema does not match expectations.
175-180
: Consistency Check indojo_name
MethodsOhayo, Sensei! The
dojo_name
method in each module returns a hardcoded string representing the event name. Please ensure that these names exactly match the corresponding struct names. Any discrepancies could lead to issues when referencing events elsewhere in the system.crates/dojo/core-cairo-test/src/tests/helpers/model.cairo (3)
9-9
: Ohayo, sensei! Correct typo in comment.There's a small typo in the comment on line 9: "differenciate" should be "differentiate".
Apply this diff to correct the typo:
-/// as the test runner does not differenciate them. +/// as the test runner does not differentiate them.
14-14
: Ohayo, sensei! Consider makingFooBaseModel
public.The
FooBaseModel
struct is not declared aspub
, which may limit its accessibility in other modules or contracts that rely on it. If it's intended to be used elsewhere, consider adding thepub
keyword.Apply this diff to make the struct public:
-struct FooBaseModel { +pub struct FooBaseModel {
107-116
: Ohayo, sensei! Refactor repeatedschema
functions to reduce code duplication.The
schema
function implementations across multiple modules (old_foo_model_bad_layout_type
,old_foo_model_member_removed
,old_foo_model_member_added_but_removed
,old_foo_model_member_added_but_moved
,old_foo_model_member_added
) contain similar code patterns. To improve maintainability and reduce redundancy, consider abstracting this functionality into a shared function or macro.For example, you could create a helper function:
fn generate_schema(model_name: felt252) -> dojo::meta::introspect::Struct { if let dojo::meta::introspect::Ty::Struct(mut s) = dojo::meta::introspect::Introspect::<super::FooBaseModel>::ty() { s.name = model_name; s } else { panic!("Unexpected schema.") } }Then, in each
schema
function, you can call this helper:fn schema(self: @ContractState) -> dojo::meta::introspect::Struct { - if let dojo::meta::introspect::Ty::Struct(mut s) = - dojo::meta::introspect::Introspect::<super::FooBaseModel>::ty() { - s.name = 'FooModelBadLayoutType'; - s - } else { - panic!("Unexpected schema.") - } + super::generate_schema('FooModelBadLayoutType') }Also applies to: 135-145, 166-175, 196-205, 227-236
crates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
25-25
: Typo in assertion messagesOhayo, sensei! The assertion messages on lines 25 and 77 contain an extra closing parenthesis
)
in'no event)'
. Please remove the extra parenthesis for clarity.Apply this diff to fix the typos:
- assert(event.is_some(), 'no event)'); + assert(event.is_some(), 'no event');Also applies to: 77-77
crates/dojo/core-cairo-test/src/tests/world/model.cairo (1)
20-21
: Ohayo, sensei! Consider creating a helper function to set testing addressesYou are repeatedly calling
starknet::testing::set_account_contract_address
andstarknet::testing::set_contract_address
with the same address in multiple test functions. For improved readability and maintainability, consider creating a helper function to handle this setup.Apply this refactor:
+fn set_testing_addresses(address: ContractAddress) { + starknet::testing::set_account_contract_address(address); + starknet::testing::set_contract_address(address); +} // Usage in your test functions: -starknet::testing::set_account_contract_address(bob); -starknet::testing::set_contract_address(bob); +set_testing_addresses(bob);Also applies to: 69-70, 81-82, 205-206, 220-221, 224-225, 247-248
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (1)
273-273
: Typo in error message stringOhayo sensei, there's an extra closing parenthesis in the error message. Please remove it for clarity.
Apply this diff to fix the typo:
- assert(event.is_some(), 'no event)'); + assert(event.is_some(), 'no event');
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (41)
Cargo.toml
(1 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/event/event.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(1 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(1 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(2 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)
💤 Files with no reviewable changes (4)
- crates/dojo/core-cairo-test/src/tests/event/event.cairo
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (15)
- Cargo.toml
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
🔇 Additional comments (48)
examples/spawn-and-move/dojo_dev.toml (1)
14-14
: Ohayo sensei! Please verify the new world address.
The world address has been updated, but we should ensure this change is intentional and properly documented.
Let's verify this address:
Consider adding a comment above the world_address explaining:
- Why this specific address is used
- When/why it might need to be updated
- How to obtain a new address if needed
[env]
rpc_url = "http://localhost:5050/"
# Default account for katana with seed = 0
account_address = "0x2af9427c5a277474c079a1283c880ee8a6f0f8fbf73ce969c08d88befec1bba"
private_key = "0x1800000000300000180000000000030000000000003006001800006600"
+# World address for the example world deployment
+# Update this when redeploying the world contract
world_address = "0x5A1F4D377330BCE53D4948BA124722929D8ECE28A27F336319343C336E3F54B"
crates/dojo/core/src/model/component.cairo (3)
1-2
: Ohayo sensei! Clean and well-structured imports.
The separation between model and meta concerns reflects good design principles and modularity.
Line range hint 27-39
: Excellent removal of versioning, sensei!
The implementation cleanly removes versioning while maintaining essential model functionality through size and definition methods. This aligns perfectly with the PR objective of removing unnecessary versioning management.
14-24
: Verify upgrade constraints in schema and layout implementations.
The schema and layout methods are crucial for enforcing upgrade constraints. These methods should ensure that:
- Layout type remains consistent (Struct or Fixed)
- Existing fields remain unchanged
- New fields are only appended at the end
Let's verify the implementation of these constraints:
crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo (2)
6-6
: Ohayo! Clean separation of concerns with interface restructuring.
The removal of functionality from IContract
and the addition of IDeployedResource
creates a more focused and maintainable interface structure. This aligns well with the PR's objective of improving resource management.
Also applies to: 18-19
20-24
: Implementation looks solid, sensei!
The IDeployedResource
implementation provides a clean way to access the contract name. The use of the template variable $name$
ensures consistency between the actual contract name and its string representation.
Let's verify that this pattern is consistently used across other contract templates:
✅ Verification successful
Ohayo! The pattern is consistently implemented, sensei!
The verification shows that the IDeployedResource
implementation pattern is consistently used across the codebase. We found two implementations:
- The template version in
contract.patch.cairo
using$name$
for dynamic contract naming - A test implementation in
core-cairo-test/src/tests/contract.cairo
following the same pattern with a static name
Both implementations maintain the same structure and purpose, confirming that the pattern is well-established and consistently applied.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent contract name implementation patterns
# across other contract templates
# Search for similar patterns in other template files
rg -g '*.cairo' -A 5 'impl.*of IDeployedResource'
Length of output: 1135
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo (2)
14-17
: Ohayo! Implementation looks good, sensei!
The transition to DojoDeployedModelImpl
implementing IDeployedResource
aligns well with the new resource management approach.
34-42
: Ohayo! The DojoStoredModelImpl implementation aligns with upgradability requirements, sensei!
The implementation correctly uses a Fixed layout type, which is one of the allowed layout types for upgradable resources as per the PR objectives. However, we should verify if this empty layout is intended for testing purposes.
✅ Verification successful
Ohayo sensei! The empty layout is indeed intended for testing purposes!
Based on the extensive codebase analysis, I can confirm that the empty layout in DojoStoredModelImpl
is intentionally used for testing attack scenarios. This is evidenced by:
- The file is located in the test directory (
core-cairo-test/src/tests/expanded/selector_attack.cairo
) - The implementation is part of an "attacker_model" module used to test security scenarios
- Other test files in the codebase also use empty layouts for testing purposes, particularly when testing model registration and upgrades
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if other test files use similar empty layouts for testing
# This helps understand if this is a common testing pattern
rg -A 5 "layout\(.*\).*\{" --type cairo
Length of output: 71
Script:
#!/bin/bash
# Let's try with a more generic search for layout patterns in Cairo files
fd -e cairo | xargs grep -l "layout" || true
# If files are found, let's examine their content
fd -e cairo | while read -r file; do
if grep -q "layout" "$file"; then
echo "=== $file ==="
cat "$file"
echo
fi
done
Length of output: 275764
Script:
#!/bin/bash
# Alternative approach: Search for similar struct patterns
fd -e cairo | while read -r file; do
if grep -q "impl.*StoredModel" "$file"; then
echo "=== $file ==="
cat "$file"
echo
fi
done
Length of output: 24773
Script:
#!/bin/bash
# Let's also check for any test files with similar patterns
fd "test.*\.cairo$" | while read -r file; do
echo "=== $file ==="
cat "$file"
echo
done
Length of output: 11382
crates/dojo/core-cairo-test/src/lib.cairo (4)
43-50
: Ohayo! Clean organization of test helpers, sensei!
The new helpers module structure provides a well-organized collection of test utilities, making them easily accessible for testing scenarios.
60-67
: Excellent symmetry with event testing patterns, sensei!
The model test cases maintain consistency with the event testing structure, providing parallel coverage for model upgradability scenarios.
72-78
: Verify status of commented-out modules.
I notice that entities
and world
modules are commented out. Could you clarify if these modules are:
- Planned for future implementation
- Temporarily disabled
- Pending removal
This will help ensure we're not missing any critical functionality.
#!/bin/bash
# Description: Check if commented modules exist in the codebase
# Test: Search for the commented-out module files
fd "entities\.cairo|world\.cairo" crates/dojo/core-cairo-test/src/tests/world/
52-58
: Well-structured event test cases for upgradability checks!
The event types cover various upgrade scenarios (bad layout, member removal, etc.) aligning perfectly with the PR's objective of implementing upgradability checks.
Let's verify the test coverage:
✅ Verification successful
Ohayo sensei! Event upgradability tests are well implemented and verified! ✨
The test coverage for event upgradability is comprehensive, including tests for:
- Basic event upgrades (
test_upgrade_event
) - Permission checks (
test_upgrade_event_from_event_owner
,test_upgrade_event_from_event_writer
) - Various failure scenarios:
- Bad layout type (
test_upgrade_event_with_bad_layout_type
) - Member removal (
test_upgrade_event_with_member_removed
) - Member addition and removal (
test_upgrade_event_with_member_added_but_removed
) - Member movement (
test_upgrade_event_with_member_moved
)
- Bad layout type (
The event types mentioned in the review comment are properly tested with appropriate error cases, validating the upgradability checks implementation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify test coverage for event upgradability scenarios
# Test: Search for test functions in the event module
rg -t cairo "fn test.*event.*upgrade" crates/dojo/core-cairo-test/src/tests/
Length of output: 288
Script:
#!/bin/bash
# Let's check the event module directly and its test implementations
rg -t cairo "fn test.*event" crates/dojo/core-cairo-test/src/
# Also check the event module content
cat crates/dojo/core-cairo-test/src/event.cairo
Length of output: 219
Script:
#!/bin/bash
# Let's find the event module first
fd "event.cairo" crates/dojo/core-cairo-test/
# Let's also check for test files that might contain event upgrade tests
fd "test.*cairo" crates/dojo/core-cairo-test/
Length of output: 263
Script:
#!/bin/bash
# Let's check the content of the event test files
cat crates/dojo/core-cairo-test/src/tests/event/event.cairo
cat crates/dojo/core-cairo-test/src/tests/world/event.cairo
# Also check for any upgrade-related patterns in these files
rg -A 5 "FooEvent" crates/dojo/core-cairo-test/src/tests/event/event.cairo
rg -A 5 "FooEvent" crates/dojo/core-cairo-test/src/tests/world/event.cairo
Length of output: 13680
crates/dojo/core/src/lib.cairo (1)
12-13
: Ohayo! New event component module looks good, sensei!
The addition of the component
module under event
aligns well with the PR's objective of implementing event upgradability checks.
Let's verify the component module's contents:
✅ Verification successful
Ohayo! The event component module is properly implemented, sensei!
The verification shows that the component module contains well-structured implementations:
IDeployedEventImpl
- Provides name resolution for eventsIStoredEventImpl
- Handles schema and layout for eventsIEventImpl
- Manages event definitions
The implementations align perfectly with the event upgradability objectives and follow Dojo's resource management patterns.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the contents and structure of the new event component module
fd "component.cairo" --type f --exec cat {} \;
Length of output: 1945
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (1)
84-89
: Clean implementation of deployed and stored model traits, sensei!
The separation between deployed and stored model implementations provides a clear boundary for managing model lifecycles, which is essential for the upgradability system.
Let's verify that these traits are consistently implemented across other models:
✅ Verification successful
Ohayo! The model implementations are consistent across the codebase, sensei!
The search results confirm that both DojoDeployedModelImpl
and DojoStoredModelImpl
are consistently implemented in the codebase, following the same pattern as seen in:
- The model patch template in
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
- The concrete implementation in
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
Both implementations maintain the separation of concerns between deployed and stored models, with proper ABI embedding for external interaction.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistency in model implementations across the codebase
# Search for other model implementations to ensure they follow the same pattern
rg -A 2 "impl.*DojoDeployedModelImpl" --type cairo
rg -A 2 "impl.*DojoStoredModelImpl" --type cairo
Length of output: 163
Script:
#!/bin/bash
# Let's try a different approach using just pattern matching without file type
# Look for both implementations in any file
rg -A 2 "impl.*DojoDeployedModelImpl"
rg -A 2 "impl.*DojoStoredModelImpl"
# Also search for the trait definitions to understand the pattern better
rg "trait IDeployedModelImpl"
rg "trait IStoredModelImpl"
Length of output: 1955
crates/dojo/core/src/model/model.cairo (3)
1-3
: Ohayo! Import changes align with schema type updates.
The switch from introspect::Ty
to introspect::Struct
properly supports the new model upgradability requirements.
Line range hint 108-116
: Verify impact of version removal on existing model consumers.
The removal of versioning from ModelDef
aligns with the PR objectives, sensei. However, we should ensure that no existing code relies on version information for model management.
✅ Verification successful
Version removal is safe to proceed, sensei!
The search results show no active version-related code in model definitions or implementations. The only reference found is a TODO comment in sozo/ops/src/auth.rs
which is discussing a hypothetical future consideration, not actual implementation.
The removal of versioning from ModelDef
appears to be a clean change with no impact on existing model consumers.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version-related code that might need updating
echo "Checking for version-related model usage..."
rg -A 3 "version|Version" --type rust
echo "Checking for potential model version dependencies..."
ast-grep --pattern 'fn $name($_) -> u8 {
$$$
}'
Length of output: 88826
Script:
#!/bin/bash
# Check for any model version-related code in the codebase
echo "Checking for model version references..."
rg -A 3 "model.*version|version.*model" --type rust
echo "Checking for version field usage in model definitions..."
ast-grep --pattern 'struct ModelDef {
$$$
version: $_,
$$$
}'
echo "Checking for version-related model methods..."
ast-grep --pattern 'impl Model for $_ {
$$$
fn version() -> $_ {
$$$
}
$$$
}'
Length of output: 971
39-39
: Schema type change needs verification across model definitions.
The change from Ty
to Struct
is a significant modification that supports the new upgradability requirements. However, we should verify that all existing model definitions are compatible with this change.
Also applies to: 91-93
✅ Verification successful
Ohayo sensei! After analyzing the codebase, I can provide a definitive response about the schema type change:
Schema type change from Ty
to Struct
is safe to proceed
The search results show that while there are some Ty
usages in the codebase, they are in utility/parsing functions and type conversion contexts, not in actual model schema implementations. The change from Ty
to Struct
in the Model trait's schema method appears to be an internal refactoring that doesn't affect existing model definitions.
- The only
Ty
usages found are in utility functions in:torii/graphql/src/types.rs
torii/graphql/src/query/mod.rs
torii/core/src/model.rs
dojo/types/src/schema.rs
No conflicting schema implementations were found that would be broken by this change.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for any remaining usages of Ty in model definitions
# that might need updating
echo "Checking for potentially incompatible model definitions..."
rg -l "-> Ty" --type rust
echo "Checking for struct implementations that might need updates..."
ast-grep --pattern 'impl $_ of Model<$_> {
$$$
fn schema() -> $ret {
$$$
}
$$$
}'
Length of output: 88826
Script:
#!/bin/bash
# Search for schema() implementations and their return types
echo "Checking schema implementations and return types..."
ast-grep --pattern 'fn schema() -> $ret {
$$$
}'
# Search for any remaining Ty usages in model definitions
echo "Checking for Ty usages in model definitions..."
rg -A 3 "-> Ty" --type rust
# Search for Model trait implementations
echo "Checking Model trait implementations..."
ast-grep --pattern 'impl $_ of Model<$_> {
$$$
}'
Length of output: 846
Script:
#!/bin/bash
# Search for Ty usages with proper escaping
echo "Checking for Ty usages in model definitions..."
rg "\-> Ty" --type rust
# Search for schema implementations with Struct return type
echo "Checking schema implementations with Struct return type..."
ast-grep --pattern 'fn schema() -> Struct {
$$$
}'
# Search for schema implementations with Ty return type
echo "Checking schema implementations with Ty return type..."
ast-grep --pattern 'fn schema() -> Ty {
$$$
}'
Length of output: 1217
crates/torii/types-test/src/contracts.cairo (2)
Line range hint 1-5
: Ohayo sensei! The interface changes look good!
The addition of the delete
method to the IRecords
trait is clean and consistent with the existing interface design.
112-113
: Method chaining improvement looks clean, sensei!
The refactoring to use method chaining for event emission improves code readability while maintaining the same functionality.
crates/dojo/lang/src/attribute_macros/element.rs (2)
7-7
: LGTM! Import organization looks clean.
Ohayo! The import reorganization improves code readability by grouping related AST types together.
Line range hint 1-150
: Verify the impact of versioning removal.
The removal of versioning-related code (CommonStructParameters, DEFAULT_VERSION, etc.) aligns well with the PR objectives to simplify the upgrade process. However, we should verify that this change doesn't break existing contracts.
Consider documenting the new upgrade constraints in the module-level documentation:
- Same layout type requirement (Struct/Fixed)
- No changes to existing fields
- New fields must be appended at the end
Would you like me to help draft this documentation?
✅ Verification successful
Ohayo sensei! After analyzing the git history and code changes, I can now provide a definitive response about the versioning removal:
The versioning removal is safe and won't break existing contracts
The git history shows that the removed versioning code was only used for validation during compile-time:
- Removed
DEFAULT_VERSION = 1
constant - Removed
CommonStructParameters
struct that only contained version validation - Removed
get_version()
function that prevented using versions > 1
This was purely compile-time validation code that didn't affect runtime behavior or contract storage. The removal aligns with simplifying the upgrade process since:
- No runtime versioning was actually being used
- The validation was artificially limiting upgrades
- The removed code wasn't part of the contract's storage or state
Keep coding with confidence, sensei! 🚀
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for any remaining version-related code or dependencies that might need updating
# Test 1: Look for any remaining version-related code
echo "Checking for remaining version references..."
rg -i "version|versioning" --type rust
# Test 2: Look for potential upgrade-related code that might be affected
echo "Checking for upgrade-related code..."
rg -i "upgrade|migration" --type rust
# Test 3: Look for any remaining CommonStructParameters usage
echo "Checking for CommonStructParameters usage..."
rg "CommonStructParameters" --type rust
Length of output: 71128
Script:
#!/bin/bash
# Let's check for any remaining versioning-related code in the element.rs file and its dependencies
# Check for version-related code in element.rs and related files
rg -l "version|CommonStructParameters" crates/dojo/lang/src/attribute_macros/
# Check for any imports or usages of versioning-related types
ast-grep --pattern 'use $$$version$$$;' crates/dojo/lang/src/attribute_macros/element.rs
# Check for any struct definitions or trait implementations related to versioning
ast-grep --pattern 'struct $name {
$$$
version: $_,
$$$
}' crates/dojo/lang/src/attribute_macros/element.rs
# Look for any version-related function calls or methods
ast-grep --pattern 'fn $name($_) {
$$$
version$$$
$$$
}' crates/dojo/lang/src/attribute_macros/element.rs
Length of output: 400
Script:
#!/bin/bash
# Let's check the git history to see what versioning code was removed
# Check git history for removed versioning code
git log -p crates/dojo/lang/src/attribute_macros/element.rs | rg -B 5 -A 5 "CommonStructParameters|version"
# Check for any remaining references to versioning in the entire attribute_macros directory
find crates/dojo/lang/src/attribute_macros -type f -exec grep -l "CommonStructParameters\|DEFAULT_VERSION\|version" {} \;
# Look for any remaining version-related imports
rg "use.*Common.*Parameters|use.*version" crates/dojo/lang/src/attribute_macros/
# Check for any version-related function parameters
ast-grep --pattern 'fn $name($$$version$$$)' crates/dojo/lang/src/attribute_macros/element.rs
Length of output: 4871
crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo (2)
37-41
: LGTM! Clean implementation of IDeployedResource
Ohayo, sensei! The implementation correctly follows the new resource management pattern introduced for model upgradability.
43-52
: Name inconsistency between schema and dojo_name
crates/dojo/lang/src/attribute_macros/event.rs (2)
Line range hint 20-40
: Ohayo! Clean simplification of EventParameters structure.
The removal of the common parameters and focus on just the historical field aligns perfectly with the PR's objective of removing versioning management. The simplified structure maintains backward compatibility while reducing complexity.
Line range hint 20-63
: Verify complete removal of versioning logic.
The changes align with removing versioning management, but let's verify no residual versioning logic exists in related files.
✅ Verification successful
Ohayo sensei! The versioning removal is complete and clean
The codebase scan shows that versioning has been properly removed from event handling. The only remaining references are to historical
flags, which are a separate feature for event tracking and not related to versioning management.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining version-related code in event implementations
rg -i "version" --type rust -g "event*.rs" -g "!target/*"
# Search for potential version-related types or traits
ast-grep --pattern 'trait $name {
$$$
version($$$) {
$$$
}
$$$
}'
Length of output: 283
Script:
#!/bin/bash
# Let's check the event_message.rs file content for context
cat crates/torii/core/src/processors/event_message.rs
# Also check for any version-related imports or dependencies
rg -i "version" --type toml
# Check for any version-related structs or enums
ast-grep --pattern 'struct $name {
$$$
version: $_,
$$$
}'
ast-grep --pattern 'enum $name {
$$$
Version($$$),
$$$
}'
Length of output: 54380
Script:
#!/bin/bash
# Let's check for any historical version references in event-related files
rg -i "historical" --type rust -g "event*.rs" -A 2 -B 2
# Check for any version-related attributes or macros
ast-grep --pattern '#[derive($$$)]
struct $name {
$$$
}'
# Look for any version-related constants or parameters
rg -i "const.*version|version.*=.*" --type rust -g "event*.rs"
Length of output: 8638
crates/dojo/world/src/contracts/model.rs (1)
176-176
: Ohayo sensei! Verify schema parsing behavior for upgradability checks.
The change to wrap the result in Ty::Struct
aligns with the PR's objective to enforce layout type consistency during upgrades. However, we should verify that this properly enforces the upgradability rules.
Let's check the schema parsing behavior:
Consider adding explicit validation in the schema parsing to enforce:
- No changes to existing field positions
- New fields only at the end of the resource
- Layout type consistency (Struct/Fixed)
✅ Verification successful
Ohayo sensei! Schema parsing change is correctly enforcing upgradability rules.
The change to wrap the result in Ty::Struct
aligns with the comprehensive test suite that verifies schema validation during model upgrades. The tests confirm proper handling of:
- Layout type consistency (
test_upgrade_model_with_bad_layout_type
) - Field position preservation (
test_upgrade_model_with_member_moved
) - Field removal prevention (
test_upgrade_model_with_member_removed
) - New field additions (
test_upgrade_model_with_member_added
)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify schema parsing and upgradability rules
# Look for any existing model upgrades to ensure they follow the new rules
# Search for model upgrade patterns
rg -A 5 "upgrade.*model|model.*upgrade"
# Search for schema-related tests
fd -e rs | xargs rg -l "test.*schema|schema.*test"
Length of output: 19669
Script:
#!/bin/bash
# Let's verify the schema parsing implementation and test coverage
# Check schema parsing implementation
ast-grep --pattern 'fn parse_schema($$$) {
$$$
}'
# Look for schema-related test cases specifically for upgrades
rg -B 2 -A 5 "test.*schema.*upgrade|upgrade.*schema.*test"
# Check for any schema validation logic
rg -A 5 "validate.*schema|schema.*validate"
# Look for struct layout validation
rg -A 5 "layout.*validate|validate.*layout"
Length of output: 206
Script:
#!/bin/bash
# Let's check the model.rs file directly and its test implementations
# Check the model schema parsing implementation
cat crates/dojo/world/src/contracts/model.rs
# Look for model upgrade test implementations
cat crates/dojo/core-cairo-test/src/tests/world/model.cairo
# Check for any schema validation in the model tests
cat crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
Length of output: 25309
crates/dojo/lang/src/attribute_macros/model.rs (2)
18-24
: Ohayo sensei! The import changes align with versioning removal.
The updated imports reflect the shift away from versioning management while maintaining the core model functionality. The code organization looks clean and focused.
Line range hint 31-70
: Ohayo sensei! We need to add upgradability checks.
Based on the PR objectives, we should add validation to ensure:
- Layout type remains consistent
- Existing fields are not modified
- New fields are only appended at the end
This will prevent breaking changes during model upgrades.
Let's verify if there are any existing upgrade validations:
crates/dojo/world/src/contracts/abigen/model.rs (3)
Line range hint 627-636
: LGTM! Schema return type properly updated.
The schema method's return type has been correctly updated to match the ModelDef struct changes, maintaining consistency throughout the codebase.
Line range hint 732-741
: LGTM! Schema return type consistently updated in reader.
The schema method's return type has been properly synchronized with the ModelContract implementation, ensuring consistency across both contract interfaces.
Line range hint 176-217
: LGTM! Version field removal aligns with PR objectives.
The changes correctly remove the version field from ModelDef and update the schema field type to be more specific (Struct instead of Ty). The serialization and deserialization logic has been properly updated to reflect these changes.
Let's verify that version-related code has been consistently removed:
✅ Verification successful
Let me gather more context about these remaining version references to ensure a thorough verification.
Ohayo sensei! After analyzing the results, I can now provide the final verification:
✅ Version field removal is properly implemented
The remaining version references found are either:
- Test data validating version attribute parsing (
plugin_test_data/model
) - Comments discussing historical context (
core-cairo-test/model.cairo
) - A TODO comment about version handling (
sozo/ops/auth.rs
)
None of these indicate actual version field usage in the codebase. The ast-grep
search also confirms no remaining version fields in structs.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version-related code
# Expect: No occurrences of version in model-related files
rg -i "version.*model"
Length of output: 603
Script:
#!/bin/bash
# Check the content of these files to understand the version references
cat crates/sozo/ops/src/auth.rs | grep -A 5 -B 5 "version.*model"
echo "---"
cat crates/dojo/lang/src/plugin_test_data/model | grep -A 5 -B 5 "version.*model"
echo "---"
cat crates/dojo/core-cairo-test/src/tests/helpers/model.cairo | grep -A 5 -B 5 "version.*model"
# Also check if there are any remaining version fields in model-related structs
ast-grep --pattern 'struct $_ {
$$$
version: $_,
$$$
}'
Length of output: 1870
crates/dojo/core/src/world/world_contract.cairo (5)
42-45
: LGTM! Clean import additions for resource upgradability.
The new imports from dojo::meta
provide the necessary types and traits for implementing resource upgradability checks.
357-357
: LGTM! Consistent entity ID calculation.
The change to use entity_id_from_keys
aligns with the standard pattern used throughout the codebase.
436-436
: LGTM! Improved type safety with IDeployedResourceDispatcher.
The consistent use of IDeployedResourceDispatcher
across all resource-related functions enhances type safety and maintainability.
Also applies to: 482-482, 540-540, 586-586, 665-665, 720-720
508-511
: LGTM! Robust upgradability checks added.
The addition of assert_resource_upgradability
checks in both event and model upgrades ensures safe schema evolution.
Also applies to: 612-615
Line range hint 1028-1059
: Consider improving error handling for non-Dojo contracts.
The current implementation assumes all contract callers are Dojo contracts. While this works for the current use cases, it might cause issues when integrating with external contracts.
Consider adding a try-catch mechanism:
-let d = IDeployedResourceDispatcher { contract_address: caller };
-format!("Contract `{}`", d.dojo_name())
+match try_selector_from_address(caller) {
+ Option::Some(name) => format!("Contract `{}`", name),
+ Option::None => format!("External contract `{:?}`", caller)
+}
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (3)
7-10
: Ohayo, Sensei! Clarify the Usage of #[dojo::event]
Attribute
The comments mention that the event contracts are written without the #[dojo::event]
attribute to avoid naming conflicts, yet from line 21 onwards, the #[dojo::event]
attribute is applied to the event structs. Please verify if this is intentional or if the attribute should be omitted to align with the initial comment and testing setup.
7-11
: Duplicate Comment on #[dojo::event]
Usage
Sensei, the comment regarding the use of the #[dojo::event]
attribute appears redundant with earlier comments. Consider consolidating or rephrasing to maintain clarity and avoid repetition.
63-78
:
Ensure Correct Initialization of Event Resources
Sensei, in the deploy_world_for_event_upgrades
function, you're registering event resources using TEST_CLASS_HASH
from various modules like old_foo_event_bad_layout_type
. Please confirm that these modules are correctly imported and their TEST_CLASS_HASH
constants are properly initialized. Missing or incorrect class hashes could lead to issues during world deployment.
Run the following script to verify module imports and TEST_CLASS_HASH
initialization:
✅ Verification successful
This will help us locate the module files and verify their TEST_CLASS_HASH definitions, even if they're in separate files rather than in the main event.cairo file.
This will help us verify if the event modules mentioned in the function are properly defined in the same file.
All Event Modules Properly Defined and Used, Sensei!
Ohayo! After verifying the codebase, I can confirm that all the event modules (old_foo_event_bad_layout_type
, old_foo_event_member_removed
, old_foo_event_member_added_but_removed
, old_foo_event_member_added_but_moved
, and old_foo_event_member_added
) are properly defined in the same file. Each module follows the correct structure with proper storage and implementation traits. The usage of TEST_CLASS_HASH
in the deploy_world_for_event_upgrades
function is consistent with the module definitions.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all old event modules are imported and have initialized TEST_CLASS_HASH.
# Expected: Each module should define TEST_CLASS_HASH.
for module in old_foo_event_bad_layout_type old_foo_event_member_removed old_foo_event_member_added_but_removed old_foo_event_member_added_but_moved old_foo_event_member_added; do
rg -A 5 "pub mod $module" crates/dojo/core-cairo-test/src/tests/helpers/event.cairo | rg "const TEST_CLASS_HASH"
done
Length of output: 1586
Script:
#!/bin/bash
# Let's check if these modules exist in separate files
fd -e cairo old_foo_event
# Then let's check the content of these files for TEST_CLASS_HASH
rg "TEST_CLASS_HASH" -A 2 -B 2
Length of output: 61935
Script:
#!/bin/bash
# Let's check if these specific event modules exist and have TEST_CLASS_HASH defined
rg -A 5 "mod old_foo_event_" crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
Length of output: 1047
crates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
46-49
: Ohayo, sensei! The #[should_panic]
attribute syntax issue persists
The syntax for #[should_panic]
attributes is incorrect in multiple places. Please refer to the previous comment regarding the correct syntax and apply the necessary changes throughout the file.
Also applies to: 129-134, 141-146, 153-158, 169-173, 181-185, 199-201, 220-221, 229-230
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (8)
77-78
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the previous comment about the expected
parameter being a string literal is still applicable here.
90-91
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the issue with the expected
parameter needing to be a string literal persists in this code segment.
193-196
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the prior feedback regarding the expected
parameter applies here as well.
225-226
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the earlier comment about using a string literal for the expected
parameter remains relevant.
237-238
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the previous advice on the expected
parameter is still valid for this segment.
290-295
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the issue with the expected
parameter needing to be a string literal persists here.
322-327
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the previous comment about the expected
parameter applies to this code segment as well.
343-344
: Incorrect usage of expected
parameter in #[should_panic]
Ohayo sensei, the prior feedback regarding the expected
parameter is still applicable here.
fn layout(self: @ContractState) -> dojo::meta::Layout { | ||
// Should never happen as dojo::event always derive Introspect. | ||
dojo::meta::Layout::Fixed([].span()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Review the Implementation of the layout
Function
Sensei, the layout
function returns dojo::meta::Layout::Fixed([].span())
with a comment stating it should never happen since #[dojo::event]
always derives Introspect
. However, returning an empty layout might lead to issues if this code path is ever executed. Consider implementing proper error handling or ensuring that this case cannot occur to prevent potential runtime errors.
fn plz_more_tps(self: @ContractState) -> felt252 { | ||
'daddy' | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential type mismatch: returning a string literal as felt252
Ohayo sensei, the function plz_more_tps
is expected to return a felt252
, but it returns a string literal 'daddy'
. Please consider converting the string to a felt252
or returning an appropriate numeric value.
let quantum_dispatcher = IQuantumLeapDispatcher { contract_address: base_address }; | ||
assert(quantum_dispatcher.plz_more_tps() == 'daddy', 'quantum leap failed'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential type mismatch in assertion
Ohayo sensei, in the assertion, you're comparing a felt252
to a string literal 'daddy'
. Ensure both sides of the comparison are of the same type to avoid unexpected behavior.
431b031
to
8a20705
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (25)
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo (1)
14-17
: Ohayo! Implementation looks good but could use documentation.The switch to
IDeployedResource
aligns well with the new upgradability system, sensei. The implementation is clean and minimal.Consider adding a doc comment explaining this contract's role in testing selector attacks:
+/// Test contract implementing IDeployedResource for selector attack verification pub impl DojoDeployedModelImpl of dojo::meta::IDeployedResource<ContractState> {
crates/dojo/core-cairo-test/src/tests/helpers/model.cairo (2)
7-11
: Ohayo, sensei! Consider enhancing the documentation.While the current comment explains why these models are defined without the
dojo::model
attribute, it would be helpful to document the specific test scenario each model is designed to validate (e.g., what makesFooModelBadLayoutType
"bad").
58-71
: Ohayo! Clean deployment function implementation.The function effectively sets up a test world with all necessary model contracts. While
unwrap()
is used for error handling, this is acceptable in a test context. However, consider adding a comment explaining that panics are expected/acceptable here.crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (1)
110-115
: Enhance documentation for ensure_unique, sensei!While the implementation is solid, consider expanding the comment to explain:
- Why unique class hashes are important for model upgradability
- How the hash is computed from model and member names
- What problems this prevents (e.g., accidental model collisions)
- // Ensures the generated contract has a unique classhash, using - // a hardcoded hash computed on model and member names. + // Ensures the generated contract has a unique classhash to prevent accidental + // model collisions during upgrades. The hash is deterministically computed + // from the model name and its member names, making it consistent across + // deployments but unique to this model's structure.crates/dojo/core/src/model/model.cairo (2)
1-3
: Ohayo! The import changes align well with the new upgradability requirements, sensei!The transition from
introspect::Ty
tointrospect::Struct
provides better type safety and validation capabilities, which are essential for enforcing the strict upgradability conditions mentioned in the PR objectives.
Line range hint
108-117
: Clean removal of versioning from ModelDef, sensei!The definition method now returns a version-free ModelDef, focusing on essential elements for upgradability validation: layout, schema, and size information. This aligns perfectly with the PR's goal of removing versioning management while maintaining strict upgrade controls.
crates/torii/types-test/src/contracts.cairo (1)
Ohayo sensei! The delete implementation needs some event emission! 🎯
Based on the codebase analysis, I can see that:
- The codebase extensively uses events for tracking model changes
- There's a
StoreDelRecord
event that's emitted in other delete operations- The current delete implementation correctly erases the models but doesn't emit any events
Let's improve the implementation by adding event emission:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); let record: Record = world.read_model(record_id); let record_sibling: RecordSibling = world.read_model(record_id); let subrecord_id = record_id + 1; let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); world.erase_model(@record); + // Emit deletion event for record + world.emit_event( + @StoreDelRecord { + selector: dojo::model::Model::<Record>::selector(), + entity_id: record_id.into() + } + ); world.erase_model(@record_sibling); + // Emit deletion event for record_sibling + world.emit_event( + @StoreDelRecord { + selector: dojo::model::Model::<RecordSibling>::selector(), + entity_id: record_id.into() + } + ); world.erase_model(@subrecord); + // Emit deletion event for subrecord + world.emit_event( + @StoreDelRecord { + selector: dojo::model::Model::<Subrecord>::selector(), + entity_id: (record_id, subrecord_id).into() + } + ); }🔗 Analysis chain
Line range hint
116-131
: Critical concerns in delete implementation, sensei! 🚨The delete implementation has several potential issues that need attention:
- Missing error handling for non-existent records
- Hardcoded assumption that
subrecord_id = record_id + 1
- No events emitted for deletion tracking
Consider applying these improvements:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); - let record: Record = world.read_model(record_id); - let record_sibling: RecordSibling = world.read_model(record_id); + // Handle potential errors + match world.try_read_model::<Record>(record_id) { + Option::Some(record) => { + let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; - let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); + // Read all subrecords associated with this record + let subrecords = world.get_models_with_key1::<Subrecord>(record_id); - world.erase_model(@record); - world.erase_model(@record_sibling); - world.erase_model(@subrecord); + world.erase_model(@record); + world.erase_model(@record_sibling); + + // Erase all associated subrecords + subrecords.iter().for_each(|subrecord| { + world.erase_model(@subrecord); + }); + + // Emit deletion event + world.emit_event( + @RecordDeleted { record_id } + ); + }, + Option::None => { + panic!("Record not found"); + } + } }Let's verify if there are any existing deletion events in the codebase:
Let me also check the actual model definitions and their usage:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any existing deletion events rg -l "Deleted|Removal|Erased" --type cairoLength of output: 75
Script:
#!/bin/bash # Search for any event-related code patterns in Cairo files fd "\.cairo$" | xargs cat | grep -i "event\|emit" # Also search for struct definitions that might be events fd "\.cairo$" | xargs cat | grep -i "struct.*deleted\|struct.*removed"Length of output: 25719
Script:
#!/bin/bash # Look for Record and Subrecord model definitions fd "\.cairo$" | xargs cat | grep -A 5 "struct.*Record" # Check if there are any existing delete or erase operations fd "\.cairo$" | xargs cat | grep -i "delete\|erase"Length of output: 9090
crates/dojo/lang/src/attribute_macros/element.rs (2)
86-90
: Ohayo! Nice hash implementation, sensei!The
compute_unique_hash
function provides a robust way to generate deterministic hashes for structs. The use of Poseidon hash with a combination of packing status and struct text ensures uniqueness and cryptographic security.This hash can be effectively used for:
- Detecting incompatible struct changes during upgrades
- Verifying struct integrity across the system
- Creating unique identifiers for struct versions
Consider documenting these use cases in the function's documentation to help other developers understand its importance in the upgradability system.
Line range hint
1-1
: Ohayo! Good architectural decision on versioning removal, sensei!The removal of version-related code (
CommonStructParameters
,DEFAULT_VERSION
, etc.) aligns well with the new upgradability strategy. Instead of explicit versioning, the system now relies on structural compatibility checks, which is a more robust approach.This change:
- Reduces complexity by removing manual version management
- Enforces compatibility through structural checks rather than version numbers
- Makes upgrades more predictable and safer
Consider adding a migration guide in the documentation to help users understand how to handle upgrades in the new system.
crates/dojo/lang/src/attribute_macros/event.rs (1)
167-169
: Document the unique hash computation purpose and parameters.The addition of
unique_hash
is crucial for upgradability checks, but the purpose of thefalse
parameter incompute_unique_hash
needs documentation.Add a comment explaining:
// Compute a unique hash for the event structure to enforce upgradability rules // The `false` parameter indicates ... let unique_hash = compute_unique_hash(&struct_ast.as_syntax_node().get_text(db), false).to_string();Also applies to: 180-180
crates/dojo/lang/src/attribute_macros/model.rs (1)
Line range hint
1-207
: Ohayo sensei! Consider documenting upgradability constraints.While the code changes look solid, it would be beneficial to add documentation about the new upgradability constraints mentioned in the PR objectives:
- Same layout type requirement (Struct/Fixed)
- No changes/movements of existing fields
- New fields must be appended at the end
Consider adding these as doc comments at the top of the file or in the
DojoModel
struct documentation.#[derive(Debug, Clone, Default)] pub struct DojoModel {} + +/// Upgradability constraints for models: +/// - Must maintain the same layout type (Struct/Fixed) +/// - Existing fields cannot be changed or moved +/// - New fields can only be appended at the end of the resourcecrates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
48-97
: Consider adding more edge cases for event registration.Ohayo, sensei! While the current tests cover basic success and failure scenarios, consider adding tests for:
- Registration with invalid class hash
- Registration with empty event name
- Multiple registrations of the same event
crates/dojo/core-cairo-test/src/tests/world/model.cairo (4)
74-86
: Ohayo, sensei! Consider extracting event validation to a helper functionThe event validation pattern is repeated across multiple tests. Consider extracting it into a helper function to improve maintainability and reduce code duplication.
fn assert_model_registered_event( event: Option<world::Event>, expected_name: felt252, expected_namespace: felt252, expected_class_hash: ClassHash ) { match event { Option::Some(world::Event::ModelRegistered(event)) => { assert(event.name == expected_name, 'bad event name'); assert(event.namespace == expected_namespace, 'bad event namespace'); assert(event.class_hash == expected_class_hash, 'bad event class_hash'); assert( event.address != core::num::traits::Zero::<ContractAddress>::zero(), 'bad event prev address' ); }, _ => core::panic_with_felt252('no ModelRegistered event') } }
160-236
: Ohayo, sensei! Well-organized upgrade test suiteThe upgrade tests provide comprehensive coverage of various scenarios:
- Basic model upgrades
- Layout type validation
- Field removal detection
- Field movement detection
- Field addition validation
Consider grouping these related tests using a test module to improve organization:
mod tests_model_upgrades { #[test] fn test_upgrade_model() { ... } #[test] fn test_upgrade_model_with_bad_layout_type() { ... } // ... other upgrade tests }
283-285
: Ohayo, sensei! Enhance security test documentationThe comment for the malicious contract test could be more detailed to better explain the security implications and expected behavior.
Consider expanding the comment to:
// This test verifies that malicious contracts cannot bypass access control by directly // calling register_model. The test currently fails with CONTRACT_NOT_DEPLOYED since // the calling contract is not a registered Dojo contract. In production, this prevents // unauthorized contracts from registering models even if they somehow obtain owner permissions.
1-297
: Ohayo, sensei! Excellent test coverage with room for minor improvementsThe test suite provides comprehensive coverage of model registration and upgrades. A few suggestions to consider:
- Add edge cases for very large structs or complex field types
- Consider testing concurrent registration attempts
- Add performance tests for large-scale model operations
Would you like assistance in implementing any of these additional test cases?
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (3)
167-189
: Ohayo sensei! Consider adding more assertions for event validationThe event validation in
test_deploy_contract_for_namespace_owner
could be more thorough. Consider adding assertions to verify the deployer's address and timestamp.Add these assertions after the existing ones:
assert( event.address != core::num::traits::Zero::<ContractAddress>::zero(), 'bad contract address' ); + assert(event.deployer == bob, 'wrong deployer'); + assert(event.timestamp > 0, 'invalid timestamp');
275-287
: Ohayo sensei! Enhance upgrade event validationThe event validation in
test_upgrade_contract_from_resource_owner
could be more thorough. Consider validating additional event fields.Add these assertions within the event match block:
if let world::Event::ContractUpgraded(event) = event.unwrap() { assert( event.selector == dojo::utils::selector_from_namespace_and_name( DOJO_NSH, @contract_name ), 'bad contract selector' ); assert(event.class_hash == class_hash, 'bad class_hash'); + assert(event.upgrader == bob, 'wrong upgrader'); + assert(event.timestamp > 0, 'invalid timestamp'); + assert(event.contract_address == contract_address, 'wrong contract'); } else { core::panic_with_felt252('no ContractUpgraded event'); };
1-361
: Ohayo sensei! Overall assessment looks good!The test coverage is comprehensive, covering various scenarios for contract deployment and upgrades. The code effectively tests access control, error cases, and event emissions.
Consider adding these test scenarios in future updates:
- Upgrade to an invalid class hash
- Concurrent upgrade attempts
- Gas consumption benchmarks for upgrades
crates/dojo/core/src/world/world_contract.cairo (1)
975-1010
: Ohayo, sensei! Robust upgradability checks implementationThe implementation thoroughly validates upgrade compatibility with clear requirements:
- Same layout type preservation
- Existing field protection
- Append-only new fields
Consider enhancing error messages to include specific details about which validation failed (e.g., which fields were modified).
fn assert_resource_upgradability( self: @ContractState, namespace: @ByteArray, name: @ByteArray, prev_address: ContractAddress, new_address: ContractAddress ) { let resource = IStoredResourceDispatcher { contract_address: prev_address }; let old_layout = resource.layout(); let old_schema = resource.schema(); let new_resource = IStoredResourceDispatcher { contract_address: new_address }; let new_layout = new_resource.layout(); let new_schema = new_resource.schema(); if !new_layout.is_same_type_of(@old_layout) { - panic_with_byte_array(@errors::invalid_resource_layout_upgrade(namespace, name)); + panic_with_byte_array(@errors::invalid_resource_layout_upgrade_details( + namespace, + name, + @format!("Expected {}, got {}", old_layout, new_layout) + )); } if !new_schema.is_an_upgrade_of(@old_schema) { - panic_with_byte_array(@errors::invalid_resource_schema_upgrade(namespace, name)); + panic_with_byte_array(@errors::invalid_resource_schema_upgrade_details( + namespace, + name, + @format!("Schema changes must be append-only") + )); } }crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (5)
9-9
: Ohayo, Sensei! Correct Typo in CommentThe word "differenciate" is misspelled. It should be "differentiate".
Apply this diff to fix the typo:
-/// as the test runner does not differenciate them. +/// as the test runner does not differentiate them.
32-37
: Add 'pub' Visibility toFooEventMemberRemoved
Sensei, the struct
FooEventMemberRemoved
is not declared aspub
. If this event struct needs to be accessible outside this module, consider adding thepub
keyword.Apply this diff if intended:
-struct FooEventMemberRemoved { +pub struct FooEventMemberRemoved {
41-46
: Add 'pub' Visibility toFooEventMemberAddedButRemoved
Sensei, the struct
FooEventMemberAddedButRemoved
is not declared aspub
. If it should be accessible outside this module, please consider making it public.Apply this diff if intended:
-struct FooEventMemberAddedButRemoved { +pub struct FooEventMemberAddedButRemoved {
50-55
: Add 'pub' Visibility toFooEventMemberAddedButMoved
Sensei, the struct
FooEventMemberAddedButMoved
is not declared aspub
. If external access is required, adding thepub
keyword would be beneficial.Apply this diff if intended:
-struct FooEventMemberAddedButMoved { +pub struct FooEventMemberAddedButMoved {
59-64
: Add 'pub' Visibility toFooEventMemberAdded
Sensei, the struct
FooEventMemberAdded
is currently private. If it's meant to be used outside this module, please consider declaring it aspub
.Apply this diff if intended:
-struct FooEventMemberAdded { +pub struct FooEventMemberAdded {
🛑 Comments failed to post (3)
crates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
235-254:
⚠️ Potential issueMisleading test name and error message.
Ohayo, sensei! The test name
test_upgrade_event_from_random_account
suggests testing an upgrade operation, but the test actually verifies duplicate event registration. Consider either:
- Renaming the test to
test_register_duplicate_event
, or- Modifying the test to actually test an upgrade from a random account
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
98-98:
⚠️ Potential issueCorrect String Assignment Syntax
Ohayo, Sensei! In Cairo, strings should be enclosed in double quotes. The assignment
s.name = 'FooEventBadLayoutType';
uses single quotes, which may cause a syntax error.Apply this diff to fix the issue:
- s.name = 'FooEventBadLayoutType'; + s.name = "FooEventBadLayoutType";📝 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.s.name = "FooEventBadLayoutType";
66-79: 💡 Codebase verification
⚠️ Potential issueMissing Module Declarations for Event Test Contracts
Ohayo sensei! After reviewing the codebase, I found that while the event structs are defined, the referenced modules (
e_FooEventMemberRemoved
, etc.) and theirTEST_CLASS_HASH
constants are missing. The code expects these modules to be defined similarly to theold_foo_event_bad_layout_type
module, but they are not present.
- Missing module declarations for:
e_FooEventMemberRemoved
e_FooEventMemberAddedButRemoved
e_FooEventMemberAddedButMoved
e_FooEventMemberAdded
Each of these modules should be defined with the
#[starknet::contract]
attribute and include theTEST_CLASS_HASH
constant, following the pattern shown in theold_foo_event_bad_layout_type
module.🔗 Analysis chain
Verify References to Event Modules and Constants
Sensei, in the
deploy_world_for_event_upgrades
function, the code referencesTEST_CLASS_HASH
from modules likee_FooEventMemberRemoved
and others. Please ensure that these modules and their constants are correctly defined and imported.Run the following script to verify the existence of the referenced modules and constants:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the referenced modules and constants are defined. # Expected: The modules and constants should be found in the codebase. # Check for module definitions rg -F "mod e_FooEventMemberRemoved" --type cairo rg -F "mod e_FooEventMemberAddedButRemoved" --type cairo rg -F "mod e_FooEventMemberAddedButMoved" --type cairo rg -F "mod e_FooEventMemberAdded" --type cairo # Check for TEST_CLASS_HASH constants rg -F "const TEST_CLASS_HASH" --type cairoLength of output: 410
Script:
#!/bin/bash # Let's try without the --type cairo flag since it's not recognized # First, let's check for module definitions rg -F "mod e_FooEventMemberRemoved" rg -F "mod e_FooEventMemberAddedButRemoved" rg -F "mod e_FooEventMemberAddedButMoved" rg -F "mod e_FooEventMemberAdded" # Check for TEST_CLASS_HASH constants rg -F "const TEST_CLASS_HASH" # Let's also check the directory structure to understand where these files might be fd . crates/dojo/core-cairo-test/src/tests/Length of output: 2050
Script:
#!/bin/bash # Let's check the content of the event-related files for our modules and TEST_CLASS_HASH rg -l "FooEvent" crates/dojo/core-cairo-test/src/tests/event/ cat crates/dojo/core-cairo-test/src/tests/event/event.cairo # Also check the helpers directory since our file is there rg -l "FooEvent" crates/dojo/core-cairo-test/src/tests/helpers/ cat crates/dojo/core-cairo-test/src/tests/helpers/event.cairoLength of output: 4107
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (23)
crates/dojo/core/src/model/component.cairo (2)
5-11
: Clean trait implementation for deployment concerns!The separation of
IDeployedModelImpl
demonstrates good architectural design by isolating deployment-specific functionality. This separation will make future upgrades more manageable and safer.This clean separation of concerns will be particularly valuable for the new upgradability checks, as it provides a clear boundary between deployment and storage aspects of the model.
Line range hint
27-39
: Ohayo! Clean removal of versioning, sensei!The implementation successfully removes version management while maintaining essential model functionality. This aligns perfectly with the PR objectives.
The removal of versioning in favor of structural upgrade checks is a more robust approach, as it enforces compatibility through actual schema structure rather than arbitrary version numbers.
crates/dojo/core-cairo-test/src/lib.cairo (1)
63-69
: Consider documenting the commented-out modules, sensei! 📝While the new module structure in the
world
namespace looks good, there are some commented-out modules (entities
andworld
). It would be helpful to add a comment explaining why these are commented out and if they will be needed in the future.Consider adding documentation like this:
- //mod entities; + // TODO: entities module temporarily disabled until <reason> - //mod world; + // TODO: world module temporarily disabled until <reason>crates/dojo/core-cairo-test/src/tests/helpers/model.cairo (1)
58-71
: Ohayo! Consider enhancing error handling in deploymentThe deployment function correctly includes all test models, but the error handling could be more robust. The current
.try_into().unwrap()
pattern might panic silently.Consider adding error context:
- TestResource::Model(m_FooModelBadLayoutType::TEST_CLASS_HASH.try_into().unwrap()), + TestResource::Model( + m_FooModelBadLayoutType::TEST_CLASS_HASH + .try_into() + .expect('Failed to convert FooModelBadLayoutType class hash') + ),crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (1)
84-89
: Clean separation of model implementations, sensei!The addition of separate implementations for deployed and stored models improves the architecture by clearly distinguishing between the two states. This separation will make the upgradability checks more maintainable.
crates/dojo/core/src/model/model.cairo (1)
39-39
: Schema type change enhances model structure validation.The change from
Ty
toStruct
in the schema method signature provides a more specific type that better represents the model's structure, enabling proper upgradability checks as required by the PR objectives.This change will help enforce the PR's requirements that:
- Layout type (Struct/Fixed) remains the same
- Existing fields cannot be changed or moved
- New fields can only be appended
crates/torii/types-test/src/contracts.cairo (1)
Line range hint
116-131
: Ohayo sensei, we need to address some critical concerns in the delete implementation! 🚨
The hardcoded
subrecord_id = record_id + 1
assumption is risky:
- It may not match the ID assigned during creation
- Could lead to deleting wrong subrecords
Missing error handling:
- No checks if records exist before reading
- Could panic if trying to delete non-existent records
Observability:
- No events are emitted for deletion tracking
- Makes it difficult to audit/monitor deletions
Consider this safer implementation:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); + // Verify record exists + assert(world.model_exists<Record>(record_id), 'Record does not exist'); let record: Record = world.read_model(record_id); let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; + // Read subrecord_id from the record if needed + // or maintain a mapping of record_id to subrecord_id + let subrecord_id = get_subrecord_id(record_id); let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); world.erase_model(@record); world.erase_model(@record_sibling); world.erase_model(@subrecord); + + // Emit deletion event for tracking + world.emit_event( + @RecordDeleted { record_id, subrecord_id } + ); }crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo (1)
45-47
: Consider enhancing the layout implementation for better test coverage.Ohayo, sensei! The current implementation returns an empty fixed layout, which might not provide sufficient test coverage for various upgrade scenarios. Consider adding test cases with different layout types and field configurations.
- dojo::meta::Layout::Fixed([].span()) + // Example layout with fields for testing upgrade scenarios + dojo::meta::Layout::Fixed([ + ('caller', dojo::meta::abi::Ty::ContractAddress), + ('a', dojo::meta::abi::Ty::Felt252), + ('b', dojo::meta::abi::Ty::U128), + ].span())crates/dojo/lang/src/attribute_macros/event.rs (1)
41-41
: Ohayo! Nice simplification of EventParameters, sensei!The removal of the
common
field and improved error handling aligns well with the PR's goal of removing versioning. The direct error reporting provides clearer diagnostics.Consider adding a doc comment to the
EventParameters
struct to explain its purpose and the meaning of thehistorical
field:+/// Parameters for event configuration. +/// - historical: Determines if the event should be stored in history. #[derive(Debug)] struct EventParameters { historical: bool, }Also applies to: 58-65
crates/dojo/lang/src/attribute_macros/model.rs (2)
155-156
: Excellent addition of packed model detection!This change is crucial for enforcing layout type consistency during upgrades, ensuring that packed models remain packed and unpacked models remain unpacked.
Consider documenting this constraint in the model's documentation to make it clear that the packed/unpacked status cannot be changed during upgrades.
179-179
: Effective integration of the unique hash!The hash is now included in the model's generated code, which will be used for upgrade validation.
Consider adding a comment in the generated code to explain the significance of this hash for upgradability checks.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (3)
99-136
: Consider adding more assertions for event propertiesOhayo, sensei! While the test covers the basic upgrade flow, consider adding assertions for:
- Event schema validation
- Previous address preservation
- Event metadata integrity
263-277
: Consider enhancing malicious contract test documentationOhayo, sensei! The comment about
CONTRACT_NOT_DEPLOYED
could be more detailed. Consider explaining:
- Why this specific error is expected
- What security implications this test covers
- How this relates to the contract deployment model
1-277
: Consider adding missing test scenariosOhayo, sensei! While the test coverage is good, consider adding tests for:
- Concurrent upgrade attempts
- Upgrade with circular dependencies
- Gas consumption for large event upgrades
- Event removal scenarios
crates/dojo/core-cairo-test/src/tests/world/model.cairo (3)
11-56
: Ohayo, sensei! Model structs look good, but could use documentationThe test model structs are well-structured to cover various upgrade scenarios. Consider adding doc comments to explain the purpose of each struct for better maintainability.
Add documentation like this:
+/// Tests model upgrade validation when layout type changes #[derive(Introspect, Copy, Drop, Serde)] #[dojo::model] pub struct FooModelBadLayoutType {
93-102
: Consider extracting error messages into constantsError message strings are duplicated across tests. Consider extracting them into constants for better maintainability and consistency.
Example:
const INVALID_NAME_ERROR: felt252 = 'Name `foo-bis` is invalid according to Dojo naming rules: ^[a-zA-Z0-9_]+$';
283-297
: Improve malicious contract test documentationThe comment about
CONTRACT_NOT_DEPLOYED
could be more descriptive. Consider explaining why this is the current behavior and if it's the intended long-term solution.Suggested comment:
-// It's CONTRACT_NOT_DEPLOYED for now as in this example the contract is not a dojo contract -// and it's not the account that is calling the register_model function. +// TODO: Currently fails with CONTRACT_NOT_DEPLOYED because: +// 1. The contract is not a dojo contract +// 2. The caller is not the account calling register_model +// Consider if this is the desired error message for malicious contract detectioncrates/dojo/core-cairo-test/src/tests/world/contract.cairo (2)
252-287
: Consider adding negative test cases for class hash validationOhayo sensei! While the test covers the happy path for contract upgrades, consider adding test cases for:
- Upgrading to an invalid class hash
- Upgrading to a class hash that doesn't implement required interfaces
341-361
: Consider adding test for concurrent upgrade attemptsOhayo sensei! To ensure robustness, consider adding a test case that verifies the behavior when multiple accounts attempt to upgrade the contract simultaneously. This would help validate the system's concurrency handling.
Would you like me to help create a test case that simulates concurrent upgrade attempts?
crates/dojo/core/src/world/world_contract.cairo (2)
436-436
: Ohayo! Nice refactoring of resource dispatchers, sensei!The unification of various dispatcher types (IEventDispatcher, IModelDispatcher) into IDeployedResourceDispatcher improves code maintainability and reduces duplication.
Consider adding a comment explaining the benefits of using IDeployedResourceDispatcher for future maintainers.
Also applies to: 482-482, 540-540, 586-586, 665-665, 720-720
975-1010
: Consider enhancing error messages with specific validation failures.The upgradability check implementation is solid, but error messages could be more descriptive to help developers understand exactly which validation failed:
- Layout type mismatch
- Schema incompatibility (field changes/moves)
Consider updating the error messages to include specific details:
- panic_with_byte_array(@errors::invalid_resource_layout_upgrade(namespace, name)); + panic_with_byte_array(@errors::invalid_resource_layout_upgrade_details( + namespace, name, @format!("Expected {}, got {}", old_layout, new_layout) + ));crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
9-9
: Correct the typo in the commentSensei, there's a typo in the comment: 'differenciate' should be 'differentiate'.
32-32
: Ensure consistent visibility for event structsSensei, some event structs are declared without the
pub
keyword (lines 32~, 41~, 50~, 59~), whileFooEventBadLayoutType
is declared aspub
. For consistency, consider addingpub
to these structs if they are intended to be public.Also applies to: 41-41, 50-50, 59-59
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (43)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/event/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(2 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(5 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (22)
- Cargo.toml
- crates/dojo/core-cairo-test/src/tests/event/event.cairo
- crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/lib.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/introspect.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
- crates/dojo/world/src/contracts/abigen/model.rs
- crates/dojo/world/src/contracts/model.rs
- examples/spawn-and-move/dojo_dev.toml
🔇 Additional comments (41)
crates/dojo/core/src/model/component.cairo (2)
1-2
: Ohayo! Clean and focused imports, sensei!
The imports are well-organized and properly reflect the architectural changes, particularly the introduction of Struct
from dojo::meta
for schema representation.
14-24
: Verify upgrade safety mechanisms, sensei!
The IStoredModelImpl
provides essential schema and layout information, but let's verify if additional checks are needed for safe upgrades.
Let's check for any existing upgrade validation code:
✅ Verification successful
Upgrade safety is properly implemented, sensei!
The verification shows that the IStoredModelImpl
is part of a robust upgrade safety system:
-
The schema and layout information are used by the world contract to perform strict upgrade validation:
- Schema upgrades are checked via
is_an_upgrade_of
method - Layout type compatibility is verified via
is_same_type_of
- New fields can only be appended at the end
- Existing fields cannot be changed or moved
- Schema upgrades are checked via
-
The implementation is protected by error messages:
invalid_resource_schema_upgrade
invalid_resource_layout_upgrade
The codebase includes comprehensive test coverage for upgrade scenarios, including tests for:
- Member removal
- Member addition
- Member reordering
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for upgrade-related validation code
echo "Searching for upgrade validation patterns..."
rg -l "upgrade|migration|compatibility" --type cairo
# Look for schema comparison logic
echo "Checking for schema comparison implementations..."
ast-grep --pattern 'fn $_(self: @$_, old_schema: Struct, new_schema: Struct)'
Length of output: 372
Script:
#!/bin/bash
# Let's try a more specific search for Cairo files
echo "Searching for upgrade patterns in .cairo files..."
fd -e cairo -x rg -l "upgrade|migration|compatibility" {} \;
# Search for schema-related implementations
echo "Looking for schema-related code..."
fd -e cairo -x rg -A 5 "schema|Struct" {} \;
# Check for any validation or comparison logic
echo "Checking validation patterns..."
fd -e cairo -x rg -A 5 "validate|compare|check" {} \;
Length of output: 34728
crates/dojo/lang/Cargo.toml (1)
39-39
: Ohayo sensei! The starknet-crypto dependency addition looks good!
The dependency is properly configured using workspace-level version management.
Let's verify the workspace configuration:
✅ Verification successful
Ohayo sensei! The starknet-crypto dependency is properly configured in the workspace!
The workspace-level version is correctly defined as 0.7.1
in the root Cargo.toml, which matches with the workspace reference in crates/dojo/lang/Cargo.toml
.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify starknet-crypto workspace configuration
# Expected: Find workspace definition of starknet-crypto version
# Test: Search for starknet-crypto in workspace Cargo.toml
rg -A 2 "starknet-crypto.*=" ./Cargo.toml
Length of output: 150
crates/dojo/core-cairo-test/src/lib.cairo (2)
43-59
: Ohayo! Nice module organization, sensei! 🎋
The new helpers
module structure looks well-organized with clear separation of concerns between general helpers, event-specific, and model-specific functionality. This aligns perfectly with the PR's objective of implementing upgradability checks.
46-49
: Verify the exported helper entities, sensei! 🔍
The large number of exported entities from the helpers module suggests these are commonly used test utilities. Let's verify they're all being used to avoid maintaining unused exports.
✅ Verification successful
Ohayo sensei! All helper entities are actively used in tests, no cleanup needed! 🎯
The search results show that all exported helper entities are being used in test files under crates/dojo/core-cairo-test/src/tests/
, serving various testing purposes:
- Test utilities like
DOJO_NSH
,deploy_world
,drop_all_events
are widely used across many test files - Model entities (
Foo
,Character
,Sword
, etc.) are used in benchmark and model tests - Contract-related helpers (
test_contract
,foo_setter
) are used in contract and ACL tests - Event-related helpers (
SimpleEvent
,e_SimpleEvent
) are used in event tests
None of these entities appear in implementation files under crates/dojo/core/src/
, confirming they are properly scoped as test utilities.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check usage of exported helper entities
# Expected: Each entity should be used in at least one test file
# Search for each exported entity
for entity in "DOJO_NSH" "SimpleEvent" "e_SimpleEvent" "Foo" "m_Foo" "foo_invalid_name" "foo_setter" \
"test_contract" "test_contract_with_dojo_init_args" "Sword" "Case" "Character" "Abilities" \
"Stats" "Weapon" "Ibar" "bar" "deploy_world" "deploy_world_and_bar" "deploy_world_and_foo" \
"drop_all_events" "IFooSetter" "IFooSetterDispatcher" "IFooSetterDispatcherTrait"; do
echo "Checking usage of $entity:"
rg "\b$entity\b" --type cairo
done
Length of output: 12140
Script:
#!/bin/bash
# Let's try searching without specifying file type since Cairo files might have different extensions
for entity in "DOJO_NSH" "SimpleEvent" "e_SimpleEvent" "Foo" "m_Foo" "foo_invalid_name" "foo_setter" \
"test_contract" "test_contract_with_dojo_init_args" "Sword" "Case" "Character" "Abilities" \
"Stats" "Weapon" "Ibar" "bar" "deploy_world" "deploy_world_and_bar" "deploy_world_and_foo" \
"drop_all_events" "IFooSetter" "IFooSetterDispatcher" "IFooSetterDispatcherTrait"; do
echo "=== Checking usage of $entity: ==="
rg "\b${entity}\b"
done
# Also let's check what files we have in the test directory
echo -e "\n=== Cairo files in the repository: ==="
fd ".*\.cairo$"
Length of output: 187631
Script:
#!/bin/bash
# Let's search for actual usage of these entities in test files
for entity in "DOJO_NSH" "SimpleEvent" "e_SimpleEvent" "Foo" "m_Foo" "foo_invalid_name" "foo_setter" \
"test_contract" "test_contract_with_dojo_init_args" "Sword" "Case" "Character" "Abilities" \
"Stats" "Weapon" "Ibar" "bar" "deploy_world" "deploy_world_and_bar" "deploy_world_and_foo" \
"drop_all_events" "IFooSetter" "IFooSetterDispatcher" "IFooSetterDispatcherTrait"; do
echo "=== Testing usage of $entity in test files: ==="
rg -l "\b${entity}\b" "crates/dojo/core-cairo-test/src/tests/"
done
# Let's also check if these are used in actual implementation files
echo -e "\n=== Checking usage in implementation files: ==="
for entity in "DOJO_NSH" "SimpleEvent" "e_SimpleEvent" "Foo" "m_Foo" "foo_invalid_name" "foo_setter" \
"test_contract" "test_contract_with_dojo_init_args" "Sword" "Case" "Character" "Abilities" \
"Stats" "Weapon" "Ibar" "bar" "deploy_world" "deploy_world_and_bar" "deploy_world_and_foo" \
"drop_all_events" "IFooSetter" "IFooSetterDispatcher" "IFooSetterDispatcherTrait"; do
echo "=== Implementation usage of $entity: ==="
rg -l "\b${entity}\b" "crates/dojo/core/src/"
done
Length of output: 30029
crates/dojo/core-cairo-test/src/tests/helpers/model.cairo (3)
1-11
: Ohayo, sensei! Clean and well-documented imports!
The file's purpose is clearly documented, and the imports are minimal and necessary.
21-55
: Ohayo! Well-structured test models for upgrade scenarios
The models are well-designed to test different upgrade scenarios:
- Member removal (
FooModelMemberRemoved
) - Member addition with removal (
FooModelMemberAddedButRemoved
) - Member movement (
FooModelMemberAddedButMoved
) - Clean member addition (
FooModelMemberAdded
)
Each model maintains consistent base fields (caller
, a
, b
) which is good for testing upgrades.
12-19
: Ohayo! Verify layout type compatibility in upgrade tests
The FooModelBadLayoutType
uses IntrospectPacked
while other models use Introspect
. This difference is intentional for testing layout type incompatibility during upgrades.
Let's verify that no other models in the codebase mix these layout types:
✅ Verification successful
Let me try a different approach to verify this more thoroughly:
This will help us see all model structs and their layout types in context, making it easier to verify if there are any conflicts or if the different layout types are used intentionally for testing purposes.
Ohayo! Layout type usage is intentionally distinct
The search results confirm that IntrospectPacked
and Introspect
are used deliberately in different contexts:
- Test files in
core-cairo-test/src/tests/meta/introspect.cairo
specifically test both layout types - The only struct using both traits is
StructIncompatibleAttrs
in test data, which is intentionally used to test incompatibility scenarios - Other models consistently use either one trait or the other, with no unintended mixing
The FooModelBadLayoutType
in the test helpers follows this pattern correctly for testing layout type changes during upgrades.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for models using both IntrospectPacked and Introspect
echo "Checking for potential layout type conflicts..."
ast-grep --pattern '#[derive(IntrospectPacked, $$$)] struct $NAME' | \
while read -r packed; do
if ast-grep --pattern "#[derive(Introspect, $$$)] struct $NAME" > /dev/null; then
echo "Warning: Found potential layout type conflict for struct: $NAME"
fi
done
Length of output: 190
Script:
#!/bin/bash
# Search for all model structs and their layout types
echo "=== Models with IntrospectPacked ==="
rg -B1 "struct.*\{" -A1 | rg -B1 "IntrospectPacked" --context 1
echo -e "\n=== Models with Introspect ==="
rg -B1 "struct.*\{" -A1 | rg -B1 "Introspect[^P]" --context 1
Length of output: 14091
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (2)
33-39
: Ohayo! Nice type safety improvement, sensei!
The schema function now correctly enforces that models must be structs and provides a clear error message if this constraint is violated. This change aligns well with the PR's objective of implementing stricter upgradability checks.
110-115
: Verify hash computation mechanism, sensei!
The ensure_unique
function is a crucial safeguard for model upgradability. Please verify:
- How the
$unique_hash$
is computed during code generation - Whether the hash includes all necessary model attributes to prevent conflicting upgrades
✅ Verification successful
Let me check the hash computation implementation more thoroughly.
Hash computation mechanism is robust, sensei!
The ensure_unique
function's hash is computed securely through:
- A Poseidon hash combining:
- A flag indicating if the model is packed (0 or 1)
- A hash of the entire struct text (including all members and attributes)
- The struct text is converted to a ByteArray and hashed using
poseidon_hash_many
This implementation ensures uniqueness based on the complete model definition, preventing conflicting upgrades since any change to model attributes, members, or packing will result in a different hash.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for hash computation logic in the codebase
rg -A 5 "unique_hash" --type rust
Length of output: 3690
Script:
#!/bin/bash
# Get the implementation of compute_bytearray_hash and poseidon_hash_many
rg -A 5 "fn compute_bytearray_hash|fn poseidon_hash_many" --type rust
# Check if there are any tests for the hash computation
rg -A 10 "test.*unique_hash" --type rust
Length of output: 1097
crates/dojo/core/src/model/model.cairo (3)
1-3
: Ohayo sensei! The import changes look good for upgradability checks.
The switch from Ty
to Struct
and addition of layout utilities aligns well with the PR's objective of implementing model upgradability checks. The Struct
type provides better structural representation needed for comparing model layouts during upgrades.
91-93
: Schema implementation maintains simplicity.
The implementation cleanly delegates to ModelDefinition
, maintaining good separation of concerns while supporting the new upgradability checks.
Line range hint 109-116
: Model definition correctly reflects versioning removal.
The ModelDef
construction has been updated to remove the version field, which aligns with the PR's goal of removing versioning management. The remaining fields provide all necessary information for upgradability checks.
Let's verify that version field references have been consistently removed:
✅ Verification successful
Version field has been completely removed from ModelDef and related code, sensei!
After thorough inspection of the codebase, I can confirm that:
- The ModelDef struct in model/mod.cairo only contains the expected fields: name, layout, schema, packed_size, and unpacked_size
- No version-related methods or traits exist in the Model implementation
- All related files in the model directory are free of version/versioning references
The changes align perfectly with the PR's goal of removing versioning management while maintaining all necessary fields for upgradability checks.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version-related code
# Expect: No occurrences of version in model definitions or traits
# Search for version-related code in model files
rg -i "version|versioning" "crates/dojo/core/src/model/"
Length of output: 56
Script:
#!/bin/bash
# Let's verify version removal more thoroughly by:
# 1. Check model.cairo for any version-related code
# 2. Search for ModelDef struct definition
# 3. Look for any version-related traits or implementations
# Check the specific model.cairo file content
cat crates/dojo/core/src/model/model.cairo
# Search for ModelDef struct definition using ast-grep
ast-grep --pattern 'struct ModelDef {
$$$
}'
# Search for any version-related traits or impls
ast-grep --pattern 'trait $_ {
fn version($$$) $$$
}'
ast-grep --pattern 'impl $_ {
fn version($$$) $$$
}'
Length of output: 4777
Script:
#!/bin/bash
# Let's check the ModelDef struct definition in the entire codebase
# and any related files that might contain version references
# Find and check content of files containing ModelDef
fd ModelDef --exec cat {}
# Also check the model directory for any other files that might contain version references
fd . crates/dojo/core/src/model/ --exec cat {}
Length of output: 13675
crates/dojo/core-cairo-test/src/tests/contract.cairo (3)
37-37
: Ohayo! New import looks good, sensei!
The addition of IDeployedResource
aligns perfectly with the PR's objective of enhancing resource management capabilities.
62-63
: Empty implementation is zen-like, sensei!
The empty ContractImpl
implementation aligns with the PR's goal of simplifying the system by removing unnecessary versioning management.
64-68
: New implementation looks solid, sensei!
The Contract_DeployedContractImpl
provides the required dojo_name
method, which is essential for resource identification in the new system. The implementation is clean and follows the established pattern.
Let's verify the consistency of the dojo_name implementation across other resources:
✅ Verification successful
The previous search failed because the file type wasn't recognized. Let's try a more generic approach to find all dojo_name implementations and the trait definition to verify the consistency.
Ohayo! Implementation is consistent with the dojo way, sensei!
The dojo_name
implementation in your contract follows the same pattern as other resources in the codebase. I can see that:
- The trait
IDeployedResource
is properly defined incore/src/meta/interface.cairo
- All implementations consistently return a
ByteArray
with a descriptive name - Your implementation matches the pattern used in other test contracts and components
The implementation is particularly aligned with other test contracts that use similar straightforward string returns, like in world/contract.cairo
and other test files.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent dojo_name implementations
# Expect: Similar implementations in other resource files
rg -A 2 "fn dojo_name.*->.*ByteArray" --type cairo
Length of output: 82
Script:
#!/bin/bash
# Let's try a more generic search for dojo_name implementations
rg -A 2 "fn dojo_name"
# Also search for trait definitions that might require dojo_name
rg "trait.*DeployedResource"
Length of output: 5862
crates/torii/types-test/src/contracts.cairo (2)
Line range hint 1-5
: Ohayo! The interface changes look solid, sensei! 🎋
The new delete
method in the IRecords
trait is well-defined and maintains consistency with the existing code structure.
112-113
: Method chaining looks clean, sensei! ✨
The refactored event emission using method chaining improves code readability while maintaining the same functionality.
crates/dojo/lang/src/attribute_macros/element.rs (3)
7-7
: Ohayo! Import changes look good, sensei!
The new imports support the transition from version-based to hash-based identification of structs.
Also applies to: 12-13
Line range hint 1-90
: Verify complete removal of versioning, sensei!
The removal of versioning code aligns with the PR objectives. Let's verify no versioning references remain.
#!/bin/bash
# Description: Check for any remaining version-related code
echo "Checking for remaining version references..."
rg -i 'version|versioning' --type rust
86-90
: Excellent hash computation implementation, sensei!
The function provides a robust way to uniquely identify structs by combining:
- Packing information (as a flag)
- Struct content hash
This approach is more reliable than version-based identification.
Let's verify the uniqueness of hashes across different structs:
✅ Verification successful
Excellent hash implementation verified, sensei!
The compute_unique_hash
function is used consistently across the codebase for:
- Model structs (with packing flag consideration)
- Event structs (always unpacked)
The implementation ensures uniqueness by combining:
- A packing flag (0 or 1)
- The struct's text content hash
This provides reliable struct identification without any risk of collisions between packed/unpacked versions of the same struct or between different structs.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potential hash collisions in struct definitions
# Look for struct definitions and their packing attributes
ast-grep --pattern 'struct $name {
$$$
}'
Length of output: 38337
Script:
#!/bin/bash
# Let's search for struct definitions and their hashing in the codebase
ast-grep --pattern 'compute_unique_hash($$$)'
# Also search for any references to this hash computation
rg -A 3 "compute_unique_hash"
Length of output: 2231
crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo (2)
66-68
: LGTM! Clean implementation of the new model definition pattern.
Ohayo, sensei! The changes effectively integrate the new trait methods while removing version management, aligning perfectly with the PR objectives.
Line range hint 37-68
: Verify test coverage for upgrade scenarios.
Ohayo, sensei! Let's ensure we have comprehensive test coverage for the new upgrade constraints mentioned in the PR objectives.
✅ Verification successful
Test coverage for upgrade scenarios is properly implemented
Ohayo, sensei! After analyzing the codebase, I can confirm that the test coverage for upgrade scenarios is comprehensive:
- The test helper file is part of a well-structured test suite in
core-cairo-test/src/tests/
- Upgrade scenarios are thoroughly tested in:
crates/dojo/core-cairo-test/src/tests/world/model.cairo
- tests model upgrades with member removal, addition and movementcrates/dojo/core-cairo-test/src/tests/world/event.cairo
- tests event upgrades with member removal, addition and movement
- The implementation properly validates schema and layout compatibility during upgrades in
crates/dojo/core/src/world/world_contract.cairo
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for test cases covering upgrade scenarios
# Test: Search for upgrade-related test cases
echo "Searching for upgrade-related test cases..."
rg -l "upgrade|layout|schema" --type cairo
# Test: Check test files for different layout types
echo "Checking test coverage for different layout types..."
rg -A 5 "Layout::(Fixed|Struct)" --type cairo
Length of output: 364
Script:
#!/bin/bash
# Let's try without file type filtering since cairo isn't recognized
echo "Searching for upgrade-related test cases..."
rg -l "upgrade|layout|schema"
echo "Checking test coverage for different layout types..."
rg -A 5 "Layout::Fixed|Layout::Struct"
# Also search for model definitions and schemas
echo "Searching for model definitions and schemas..."
rg -A 5 "ModelDef|schema"
Length of output: 260035
crates/dojo/lang/src/attribute_macros/event.rs (2)
21-21
: Ohayo! The import addition looks good, sensei!
The compute_unique_hash
import aligns with the PR's objective of implementing upgradability checks.
167-169
: Verify the unique hash computation implementation.
The hash computation is crucial for upgradability checks. Let's verify its consistency with other resource types.
Also, consider adding a comment explaining the false
parameter's purpose in the hash computation.
Also applies to: 180-180
✅ Verification successful
Let me gather more context about the is_packed
parameter by checking its usage and documentation.
Hash computation is correctly implemented for events, sensei!
The false
parameter in compute_unique_hash
for events is correct because:
- Events are never packed, unlike models which can be packed or unpacked
- Models use
is_packed
flag based on presence ofDOJO_PACKED_DERIVE
- The implementation in
element.rs
uses this boolean to includeFelt::ONE
orFelt::ZERO
in the hash computation
The consistent pattern across the codebase shows:
- Models: Variable packing based on derives
- Events: Always unpacked (false)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if unique hash computation is consistent across different resource types
# Test: Search for other compute_unique_hash usages
echo "Checking compute_unique_hash usage patterns:"
rg -A 2 "compute_unique_hash\("
# Test: Verify the second parameter (false) usage pattern
echo "\nChecking the boolean parameter patterns:"
ast-grep --pattern 'compute_unique_hash($_, false)'
Length of output: 1309
Script:
#!/bin/bash
# Check for documentation or comments about is_packed parameter
echo "Checking for documentation about is_packed:"
rg -B 3 "is_packed"
# Check the implementation of compute_unique_hash
echo "\nChecking compute_unique_hash implementation:"
ast-grep --pattern 'fn compute_unique_hash($$$)'
# Check for any model attributes that might set is_packed
echo "\nChecking for model attributes related to packing:"
rg "#\[model\]" -A 10
Length of output: 3728
crates/dojo/lang/src/attribute_macros/model.rs (3)
18-19
: Ohayo! Nice modularization of element-related functionality, sensei!
The separation of compute_unique_hash
into the element module promotes better code organization and reusability.
Line range hint 1-214
: Ohayo sensei! A note about versioning removal.
The removal of ModelParameters and versioning aligns with the PR objectives. However, to ensure a smooth transition:
Let's check for any remaining version-related code that might need cleanup:
#!/bin/bash
# Description: Check for any remaining version-related code
# Test: Search for version-related code in model implementations
rg -i "version.*model"
# Test: Search for version-related types or traits
ast-grep --pattern "trait $_ {
$$$
version
$$$
}"
160-162
: Strategic implementation of unique hash computation!
The unique hash computation considers both the struct's text and packing status, which effectively enforces the upgrade constraints:
- Same layout type (packed/unpacked)
- No changes to existing fields (captured in struct text)
- Only allows appending new fields (any modification to existing fields changes the hash)
Let's verify the hash computation behavior:
✅ Verification successful
Ohayo sensei! After analyzing the implementation, I can now provide a definitive response about the hash computation.
The unique hash computation is correctly implemented for model upgrades!
The implementation in element.rs
shows that compute_unique_hash
uses:
- A Poseidon hash combining:
- Layout type flag (is_packed: bool) -> Felt::ONE for packed, Felt::ZERO for unpacked
- Struct text hash (computed from the entire struct definition)
This ensures:
- Layout type changes are detected (packed/unpacked flag)
- Any modification to existing fields is detected (struct text hash changes)
- Only appending new fields is allowed (existing field text remains unchanged)
The implementation in the codebase matches exactly what the review comment stated about enforcing upgrade constraints through the hash computation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the hash computation correctly detects field modifications
# Test: Search for test cases that verify hash computation
rg -A 5 "compute_unique_hash.*test"
# Test: Search for examples of model upgrades in tests
rg -A 10 "model.*upgrade.*test"
Length of output: 624
Script:
#!/bin/bash
# Let's search for the compute_unique_hash implementation and its tests
ast-grep --pattern 'fn compute_unique_hash($_) {
$$$
}'
# Search for model upgrade tests with more context
rg -A 15 "test.*model.*upgrade"
# Search for hash computation in test files
fd "test" --exec rg -l "compute_unique_hash" {}
# Look for model attribute tests
fd "test" --exec rg -l "model.*attribute" {}
Length of output: 2884
Script:
#!/bin/bash
# Let's look at the implementation of compute_unique_hash
rg -A 10 "fn compute_unique_hash"
# Check the model test files more specifically
fd "model.*test" --exec cat {}
# Look for model upgrade validation tests
rg -A 10 "test.*model.*validation"
# Search for any hash comparison in tests
rg -A 5 "assert.*hash.*model"
Length of output: 34560
crates/dojo/core-cairo-test/src/tests/world/event.cairo (3)
10-46
: LGTM! Well-structured event definitions
Ohayo, sensei! The event structs are well-defined with appropriate attributes and field types. Each struct serves a specific purpose in testing different upgrade scenarios:
FooEventMemberRemoved
: Tests field removalFooEventMemberAddedButRemoved
: Tests field addition and removalFooEventMemberAddedButMoved
: Tests field movementFooEventMemberAdded
: Tests field addition
48-80
: LGTM! Comprehensive event registration test
The test properly verifies:
- Event registration by namespace owner
- Event properties (name, namespace, class_hash)
- Owner role assignment
165-214
: LGTM! Thorough upgrade validation tests
The tests effectively cover various upgrade scenarios:
- Layout type changes
- Member removal
- Member addition and removal
- Member movement
Each test properly verifies that invalid upgrades are rejected with appropriate error messages.
crates/dojo/core-cairo-test/src/tests/world/model.cairo (3)
72-72
: Fix typo in assertion message
136-136
: Fix typos in assertion messages
Also applies to: 169-169
121-297
: Ohayo, sensei! Comprehensive test coverage for model upgrades
The test suite thoroughly covers various upgrade scenarios including:
- Valid upgrades from model owner
- Permission checks
- Invalid schema changes
- Malicious attempts
Great job on ensuring robust validation of model upgrades!
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (2)
159-189
: LGTM! Well-structured test with good event validation
The test case properly validates the contract deployment process and event emission. Good job on checking all relevant fields in the event.
40-42
:
Fix type mismatch in return value
Ohayo sensei! The function returns a string literal where a felt252
is expected. While this might work due to implicit conversion, it's better to be explicit about the type.
Apply this diff to fix the type:
fn plz_more_tps(self: @ContractState) -> felt252 {
- 'daddy'
+ 'daddy'.into()
}
Likely invalid or redundant comment.
crates/dojo/core/src/world/world_contract.cairo (3)
42-45
: LGTM! Well-structured imports for resource comparison.
The new imports from dojo::meta
provide the necessary traits for comparing resource layouts and schemas during upgrades.
Line range hint 755-759
: Previous comment about non-Dojo contract handling is still valid.
Line range hint 1028-1059
: Previous comment about non-Dojo caller handling is still valid.
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
105-108
: Duplicate comment: Review the implementation of the layout
function
70-75
:
Verify the module names for event class hashes
Sensei, the module names e_FooEventMemberRemoved
, e_FooEventMemberAddedButRemoved
, e_FooEventMemberAddedButMoved
, and e_FooEventMemberAdded
used when retrieving TEST_CLASS_HASH
may not correspond to actual modules defined in the code. Please verify that these modules are correctly defined and accessible.
Run the following script to verify the existence of the modules:
✅ Verification successful
The previous search was too specific. Let's broaden our search to find any related event definitions and understand the context better. This will help us verify if these modules exist under different names or in different forms.
I see the event structs are defined, but let's verify the complete file content to ensure we understand how these events are structured and used.
All event modules are correctly defined and used
Ohayo sensei! After careful verification, I can confirm that all the event modules referenced in the code are correctly defined and used. The file shows that:
- All event structs are properly defined with the
#[dojo::event]
attribute - The
TEST_CLASS_HASH
references in thedeploy_world_for_event_upgrades
function correspond to the defined event structs - The module names match exactly with the usage:
e_FooEventMemberRemoved
,e_FooEventMemberAddedButRemoved
,e_FooEventMemberAddedButMoved
, ande_FooEventMemberAdded
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the modules are defined in the codebase.
# Expected result: The module definitions should be found.
rg -A 3 $'mod e_FooEventMemberRemoved'
rg -A 3 $'mod e_FooEventMemberAddedButRemoved'
rg -A 3 $'mod e_FooEventMemberAddedButMoved'
rg -A 3 $'mod e_FooEventMemberAdded'
Length of output: 171
Script:
#!/bin/bash
# Let's try a broader search for these event-related modules and structs
# First, let's search for any file that might contain these event definitions
fd -e cairo | xargs rg -l "FooEvent"
# Then let's look for any struct or mod definitions related to these events
rg -A 3 "(?:struct|mod).*FooEvent.*"
# Finally, let's check for TEST_CLASS_HASH usage in cairo files
rg "TEST_CLASS_HASH" -A 2 -g "*.cairo"
Length of output: 42794
Script:
#!/bin/bash
# Let's check the specific file content to understand the event structure definitions
cat crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
Length of output: 3322
8a20705
to
21369dc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (17)
crates/dojo/core-cairo-test/src/lib.cairo (1)
64-64
: Consider cleaning up commented codeThere are commented-out module declarations:
//mod entities; //mod world;If these modules are no longer needed, consider removing them entirely. If they're planned for future implementation, please add a TODO comment explaining the plan.
Also applies to: 69-69
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo (1)
Line range hint
44-63
: Clean implementation of the new resource-based architecture!The implementation nicely ties together all aspects:
- Correctly delegates to specialized traits
- Removes versioning as per PR objectives
- Maintains clear separation of concerns between deployment, storage, and model definitions
Consider documenting this pattern as it serves as a good example of the new resource-based architecture.
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (1)
64-87
: Excellent architectural design for event upgradability, sensei!The new implementation structure with separate concerns (
Deployed
,Stored
, and baseEvent
) provides a solid foundation for managing upgradable events. Theensure_abi
andensure_unique
functions are particularly valuable safeguards:
ensure_abi
: Maintains ABI compatibility during upgradesensure_unique
: Prevents class hash collisionsConsider documenting these upgrade-safety mechanisms in the module-level documentation to help other developers understand the importance of these safeguards.
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (1)
32-64
: Consider making all event structs public, sensei!The
FooEventMemberRemoved
,FooEventMemberAddedButRemoved
,FooEventMemberAddedButMoved
, andFooEventMemberAdded
structs are missing thepub
modifier, whileFooEventBadLayoutType
is public. For consistency and to ensure proper accessibility in tests, consider making all event structs public.-struct FooEventMemberRemoved { +pub struct FooEventMemberRemoved { -struct FooEventMemberAddedButRemoved { +pub struct FooEventMemberAddedButRemoved { -struct FooEventMemberAddedButMoved { +pub struct FooEventMemberAddedButMoved { -struct FooEventMemberAdded { +pub struct FooEventMemberAdded {crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (1)
84-89
: Excellent separation of concerns, sensei!The addition of distinct implementations for deployed and stored models provides a clean architecture for handling model upgradability. The ABI embedding ensures proper external accessibility.
This separation will make it easier to manage model upgrades and maintain backward compatibility.
crates/dojo/core/src/model/model.cairo (1)
39-39
: Excellent change to schema return type, sensei!The switch from
Ty
toStruct
is a key enabler for implementing model upgradability checks. This change will allow for more precise layout validation when upgrading models.This change enables:
- Strict layout type checking (Struct vs Fixed)
- Field position validation
- New field appendability verification
crates/torii/types-test/src/contracts.cairo (1)
Ohayo! The delete implementation needs refinement, sensei!
Looking at the model definitions, I can see that:
Subrecord
has a composite key of(record_id, subrecord_id)
, so the assumption ofrecord_id + 1
is incorrect- There's no direct relationship field between
Record
andSubrecord
in the model definitionsfn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); - let record: Record = world.read_model(record_id); - let record_sibling: RecordSibling = world.read_model(record_id); - - let subrecord_id = record_id + 1; - let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); - - world.erase_model(@record); - world.erase_model(@record_sibling); - world.erase_model(@subrecord); + // Delete main record if it exists + if let Option::Some(record) = world.try_read_model::<Record>(record_id) { + // Delete sibling if it exists + if let Option::Some(record_sibling) = world.try_read_model::<RecordSibling>(record_id) { + world.erase_model(@record_sibling); + } + + // Delete the main record last + world.erase_model(@record); + + // Note: Subrecords cannot be automatically deleted since there's no way to + // know which subrecord_ids are associated with this record_id + } }🔗 Analysis chain
Line range hint
116-131
: Critical concerns in delete implementation, sensei!The delete implementation has several potential issues that need attention:
The hardcoded
subrecord_id = record_id + 1
assumption is risky and might lead to incorrect deletions. Consider retrieving the correct subrecord_id from the record data or maintaining a proper relationship.Missing error handling for non-existent records. The current implementation will panic if any of the models don't exist.
No transaction safety - if any erase operation fails, the system could be left in an inconsistent state.
Consider implementing this safer version:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); - let record: Record = world.read_model(record_id); - let record_sibling: RecordSibling = world.read_model(record_id); - - let subrecord_id = record_id + 1; - let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); - - world.erase_model(@record); - world.erase_model(@record_sibling); - world.erase_model(@subrecord); + // Check if record exists first + match world.try_read_model::<Record>(record_id) { + Option::Some(record) => { + // Get associated records + if let Option::Some(record_sibling) = world.try_read_model::<RecordSibling>(record_id) { + world.erase_model(@record_sibling); + } + + // Get all subrecords associated with this record + // Note: Proper subrecord relationship should be implemented + if let Option::Some(subrecord) = world.try_read_model::<Subrecord>((record_id, record.subrecord_id)) { + world.erase_model(@subrecord); + } + + // Delete the main record last + world.erase_model(@record); + }, + Option::None => { + // Handle non-existent record case + panic!("Record not found"); + } + } }Let's verify the subrecord relationship implementation:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for subrecord relationship definition rg -t cairo "struct.*Record.*{" --context 5Length of output: 143
Script:
#!/bin/bash # Search for Record struct definition with fixed pattern rg -t cairo "struct Record" -A 5 # Search for Subrecord struct definition rg -t cairo "struct Subrecord" -A 5 # Search for RecordSibling struct definition rg -t cairo "struct RecordSibling" -A 5 # Search for any model registration of these types rg -t cairo "world\.register_model" -A 2Length of output: 277
Script:
#!/bin/bash # Search for Record struct definition without file type filter rg "struct Record" -A 5 # Search for Subrecord struct definition rg "struct Subrecord" -A 5 # Search for RecordSibling struct definition rg "struct RecordSibling" -A 5 # Search for any model registration rg "world\.register_model" -A 2Length of output: 19375
crates/dojo/lang/src/attribute_macros/element.rs (1)
86-107
: Solid implementation of unique hash computation, but could use documentation, sensei!The implementation correctly captures all structural aspects needed for upgradability verification (element name, packed status, and member details). However, adding documentation would help explain:
- The purpose of this hash in upgradability checks
- Why each component (name, packed status, members) is essential
- How this relates to the upgradability conditions mentioned in the PR description
Consider adding documentation like:
/// Computes a unique hash for a Dojo element that's used to verify upgradability. /// This hash captures the immutable structural properties that must remain unchanged during upgrades: /// - Element name /// - Packed/unpacked status /// - Member names and types in their original order /// /// This ensures that upgrades maintain backward compatibility by: /// - Preserving the same layout type /// - Preventing changes to existing fields /// - Only allowing new fields to be appendedcrates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo (1)
Line range hint
37-68
: Well-structured foundation for upgradability checks.Ohayo, sensei! The separation of concerns between
DeployedModelImpl
andStoredModelImpl
provides a solid foundation for implementing the upgradability checks mentioned in the PR objectives. This structure will make it easier to:
- Enforce layout type consistency
- Prevent changes to existing fields
- Allow new fields only at the end of the resource
Consider documenting these constraints in the code comments to help future maintainers understand the upgrade rules.
crates/dojo/lang/src/attribute_macros/event.rs (1)
167-170
: Ohayo! Please add documentation for the unique hash computation.The unique hash is crucial for upgradability checks, but its purpose and significance aren't documented. Consider adding comments explaining:
- How the hash is used in upgradability verification
- Why
false
is used for the packed parameter- What changes would affect/not affect the hash
This documentation would help maintainers understand the upgrade constraints.
Also applies to: 181-181
crates/dojo/lang/src/attribute_macros/model.rs (2)
160-163
: Essential for upgradability: Unique hash computation.The
compute_unique_hash
implementation is a key component for enforcing model upgradability rules. It generates a unique identifier based on the model's structure and packing status, which will help detect incompatible changes.Consider documenting the hash computation strategy in the codebase to help developers understand which model changes are allowed during upgrades.
Line range hint
1-224
: Ohayo sensei! Consider adding upgrade-specific validation.While the changes lay the groundwork for model upgradability checks, we might want to add explicit validation logic to ensure:
- Layout type (Struct/Fixed) remains consistent
- Existing fields aren't modified or moved
- New fields are only appended at the end
Consider adding a validation function like this:
fn validate_model_upgrade( old_model: &ItemStruct, new_model: &ItemStruct, db: &dyn SyntaxGroup ) -> Result<(), String> { // Validate layout type consistency if old_model.is_packed() != new_model.is_packed() { return Err("Cannot change model layout type during upgrade".to_string()); } // Validate existing fields let old_members = parse_members(db, &old_model.members(db).elements(db)); let new_members = parse_members(db, &new_model.members(db).elements(db)); // Check that all old fields exist unchanged in new model for old_member in old_members { if let Some(new_member) = new_members.iter().find(|m| m.name == old_member.name) { if new_member.ty != old_member.ty { return Err(format!("Field {} type cannot be changed", old_member.name)); } } else { return Err(format!("Field {} cannot be removed", old_member.name)); } } Ok(()) }crates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
216-277
: Consider enhancing error message validationOhayo, sensei! While the error cases are well-tested, consider extracting the expected error messages into constants. This would:
- Make the tests more maintainable
- Reduce duplication of error strings
- Make it easier to update error messages across all tests
Example:
const ERROR_UNAUTHORIZED: (&str, &str) = ("Account does NOT have OWNER role", "ENTRYPOINT_FAILED"); const ERROR_INVALID_LAYOUT: (&str, &str) = ("Invalid new layout", "ENTRYPOINT_FAILED");crates/dojo/core-cairo-test/src/tests/world/model.cairo (3)
11-56
: Ohayo, sensei! Model structs are well-structured but could use documentation.The model structs effectively cover different upgrade scenarios. Consider adding doc comments to explain the purpose of each struct and what upgrade scenario it tests.
Add documentation like this:
+/// Tests model upgrade with incompatible layout type changes #[derive(Introspect, Copy, Drop, Serde)] #[dojo::model] pub struct FooModelBadLayoutType {
121-236
: Ohayo, sensei! Consider adding test for field type changes.The upgrade tests comprehensively cover structural changes, but there's an opportunity to add a test case for field type modifications (e.g., changing u128 to u256).
Would you like me to help create a test case for field type changes?
283-284
: Ohayo, sensei! Enhance the explanatory comment.The current comment could be more descriptive about the security implications.
Consider updating the comment to:
-// It's CONTRACT_NOT_DEPLOYED for now as in this example the contract is not a dojo contract -// and it's not the account that is calling the register_model function. +// This test verifies that malicious contracts cannot bypass permission checks by impersonating +// authorized accounts. The CONTRACT_NOT_DEPLOYED error occurs because the calling contract +// is not a registered dojo contract, preventing potential security exploits.crates/dojo/core/src/world/world_contract.cairo (1)
Line range hint
1028-1059
: Consider handling non-Dojo contracts more gracefully.The error handling assumes the caller is either an account or a Dojo contract. As noted in the comments, this could be improved using SRC5 interface detection.
Consider implementing this improvement:
- let d = IDeployedResourceDispatcher { contract_address: caller }; - format!("Contract `{}`", d.dojo_name()) + // Check if contract implements IDescriptor using SRC5 + match ISRC5Dispatcher { contract_address: caller } + .supports_interface(IDescriptor::ID) { + true => { + let d = IDeployedResourceDispatcher { contract_address: caller }; + format!("Contract `{}`", d.dojo_name()) + }, + false => format!("Contract `{:?}`", caller) + }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (43)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/event/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(2 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(5 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (23)
- Cargo.toml
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/event/event.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/lib.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/introspect.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/component.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/Cargo.toml
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/world/src/contracts/model.rs
- examples/spawn-and-move/dojo_dev.toml
🔇 Additional comments (39)
crates/dojo/core-cairo-test/src/lib.cairo (2)
43-59
: Ohayo! Clean and well-organized module structure, sensei! 🎋
The new helpers
module structure is well-organized with clear separation into sub-modules (helpers
, event
, and model
) and explicit public exports. This modular approach enhances maintainability and makes the testing utilities more accessible.
63-63
: LGTM! Well-structured world module organization
The world module's organization with separate concerns for acl
, contract
, event
, metadata
, model
, and namespace
follows good separation of concerns principles.
Also applies to: 65-68
crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo (2)
14-17
: Ohayo! Implementation looks clean, sensei!
The switch from ContractImpl
to DojoDeployedModelImpl
aligns well with the new resource-based architecture. The implementation is minimal and focused.
35-40
: Verify if empty layout and schema are intended for testing, sensei.
The implementation returns empty spans for both layout and schema attributes. While this might be intentional for testing selector attacks, we should verify this is the desired behavior.
✅ Verification successful
Empty layout and schema are intentional for selector attack tests, sensei!
The empty layout and schema implementation is correct and intentional for this test case. The evidence shows:
-
Similar empty layouts are used in other test files:
event.cairo
: Uses empty layout for testing eventshelpers.cairo
: Uses empty layout/schema for test helpersselector_attack.cairo
: Our current test case
-
The pattern is specifically used in test files to:
- Test edge cases and attack vectors
- Mock simple implementations for testing
- Verify behavior with minimal structures
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other test files to see if empty layouts/schemas are common in tests
rg -t cairo "Layout::Fixed\(\[\]\.span\(\)\)" --context 3
rg -t cairo "children: \[\]\.span\(\)" --context 3
Length of output: 172
Script:
#!/bin/bash
# Search for layout and schema patterns without file type restriction
rg "Layout::Fixed\(\[\]\.span\(\)\)" --context 3
rg "children: \[\]\.span\(\)" --context 3
# Also search for similar patterns to catch variations
rg "Layout::Fixed\(" --context 3
rg "struct \{.*children:.*span\(\)" --context 3
Length of output: 52413
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (1)
22-28
: Ohayo! Nice type safety enhancement, sensei!
The change from Ty
to Struct
with explicit type checking improves safety and aligns well with the upgradability requirements. The panic message is clear and helpful for debugging.
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (3)
1-19
: Ohayo! The base event structure looks solid, sensei!
The imports are clean, and the FooBaseEvent
structure is well-documented with proper field types and key attributes.
105-108
: Previous comment about the layout
function implementation is still valid.
The concern about returning an empty layout and potential runtime issues remains unaddressed.
66-79
: Verify module naming consistency and existence, sensei!
There's an inconsistency in module references:
old_foo_event_bad_layout_type
is used directly- Other modules use the
e_
prefix
Let's verify that all referenced modules exist and follow consistent naming.
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (1)
33-39
: Ohayo! Nice type safety improvement, sensei!
The schema function now explicitly returns a Struct and includes runtime validation, which aligns well with the model upgradability requirements. The panic message is clear and helpful for debugging.
crates/dojo/core/src/model/model.cairo (2)
1-3
: Ohayo! Import changes look good, sensei!
The switch from Ty
to Struct
aligns perfectly with the new model upgradability requirements.
Line range hint 91-115
: Definition implementation is properly adapted, sensei!
The removal of versioning is cleanly implemented, and the ModelDef structure retains all necessary fields for upgradability validation (layout, schema, sizes).
Let's verify that versioning is consistently removed across related files:
✅ Verification successful
Ohayo! Version removal is perfectly executed, sensei!
The verification confirms that:
- No version-related references remain in the model directory
- ModelDef struct in
definition.cairo
is cleanly defined without any version field - All essential fields (name, layout, schema, packed_size, unpacked_size) are present and properly structured
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version-related code in model definitions
# Expect: No occurrences of version in model-related files
echo "Checking for remaining version references in model files..."
rg -i 'version' --type rust --type cairo crates/dojo/core/src/model/
Length of output: 227
Script:
#!/bin/bash
# Let's try a more direct approach without file type filtering
echo "Checking for version references in model directory..."
rg -i 'version' crates/dojo/core/src/model/
# Also check for ModelDef struct definition to ensure version field is removed
echo -e "\nChecking ModelDef struct definition..."
rg 'struct ModelDef' -A 10 crates/dojo/core/src/model/
Length of output: 789
crates/torii/types-test/src/contracts.cairo (2)
Line range hint 1-5
: Ohayo! Clean interface extension, sensei!
The addition of the delete method to the IRecords trait is well-structured and maintains consistency with the existing types.
112-113
: Method chaining improves readability, sensei!
The refactored event emission using method chaining enhances code readability while maintaining the same functionality.
crates/dojo/lang/src/attribute_macros/element.rs (2)
7-7
: Ohayo! New imports look good, sensei!
The addition of MemberAst
and hash-related imports aligns perfectly with the new functionality for computing unique hashes and handling model upgradability.
Also applies to: 12-13
Line range hint 1-107
: Verify complete removal of versioning references
The versioning-related code has been removed as intended, but let's verify there are no remaining references that might cause confusion.
✅ Verification successful
Let me search more specifically for versioning in the element module and related code:
Ohayo sensei! After checking the codebase, I can now provide a clear response about the versioning removal:
✓ Versioning removal is complete and correct
The code changes in element.rs
and related files show no remaining versioning references that would need attention. The only version-related entry found is the standard workspace version configuration in Cargo.toml, which is expected and should remain.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version-related code in the codebase
# that might need to be updated for consistency
# Search for version-related terms in the codebase
echo "Searching for potential version references..."
rg -i "version|versioning" \
--type rust \
--glob "!target/" \
-g "!Cargo.toml" \
-g "!Cargo.lock"
Length of output: 38269
Script:
#!/bin/bash
# Search for version-related code in element.rs and related files
rg -i "version" \
--type rust \
-g "crates/dojo/lang/src/attribute_macros/element.rs" \
-g "crates/dojo/lang/src/attribute_macros/mod.rs" \
-g "crates/dojo/lang/src/lib.rs" \
-A 3 -B 3
# Check if there are any version-related imports or dependencies
rg -i "version" \
--type rust \
-g "crates/dojo/lang/Cargo.toml"
Length of output: 280
crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo (3)
37-41
: LGTM! Test-specific implementation noted.
Ohayo, sensei! The implementation of DeployedModelImpl
looks good. The intentionally different name ("foo-bis") appears to be for testing purposes, which is appropriate in this context.
66-68
: LGTM! Clean delegation to specialized implementations.
Ohayo, sensei! The definition
method has been nicely refactored to use the new specialized implementations, which aligns well with the PR's objective of improving resource management.
44-47
: Verify the empty fixed layout implementation.
Ohayo, sensei! The layout
method returns an empty fixed layout. Please confirm if this is intentional for testing purposes or if it should include the actual model fields.
✅ Verification successful
Empty fixed layout is correct for this test helper
Ohayo, sensei! After analyzing the codebase, I can confirm that the empty fixed layout is intentional and correct for this test helper. Here's why:
- This is in a test helper file (
core-cairo-test/src/tests/helpers/helpers.cairo
) specifically designed for testing purposes - Other test files like
selector_attack.cairo
also use empty fixed layouts for similar test scenarios - The empty layout pattern (
Layout::Fixed([].span())
) is used in test contexts where the actual layout implementation is not relevant for the test case
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if other test files use non-empty layouts
rg -A 3 "Layout::Fixed\(" --type cairo
Length of output: 70
Script:
#!/bin/bash
# Search for Layout::Fixed pattern in cairo files using ast-grep
ast-grep --pattern 'Layout::Fixed($$$)'
# Also search for any Layout implementations to understand the context
ast-grep --pattern 'fn layout($$$) -> dojo::meta::Layout {'
Length of output: 733
Script:
#!/bin/bash
# Let's search for any test files or examples that might show the intended usage
rg -g "*.cairo" "IStoredResource" -A 5
# Also check for any documentation or comments about Layout::Fixed
rg -g "*.cairo" "Layout::Fixed" -B 2 -A 2
Length of output: 24261
crates/dojo/lang/src/attribute_macros/event.rs (2)
21-21
: Ohayo sensei! LGTM on the compute_unique_hash import!
The addition of compute_unique_hash
import aligns well with the PR's objective of implementing upgradability checks.
Line range hint 167-181
: Verify impact on existing events.
The removal of versioning and addition of unique hash computation represents a significant change in how events are handled.
Let's verify the impact on existing events:
crates/dojo/lang/src/attribute_macros/model.rs (3)
18-22
: Ohayo sensei! LGTM on the import changes!
The new imports align well with the PR's objective of implementing model upgradability checks. The compute_unique_hash
import is particularly relevant for tracking model changes.
180-180
: LGTM on hash integration!
The unique hash is properly integrated into the RewriteNode interpolation, ensuring it's available for upgrade validation.
155-156
: Verify packed model handling implications.
The is_packed
flag determination is crucial for model upgradability. We should ensure that changing a model's packed status is properly restricted during upgrades.
✅ Verification successful
Ohayo sensei! Based on the evidence gathered from the codebase, I can now provide a conclusive response:
Model packed status changes are properly validated during upgrades
The codebase shows robust validation for model upgrades through:
- Schema validation that prevents invalid upgrades (as seen in
world/errors.cairo
) - Test coverage for bad layout types and invalid schema changes
- Unique hash computation that includes the packed status (
compute_unique_hash
function takesis_packed
as a parameter)
The packed status is part of the model's identity and schema validation, making it impossible to change during upgrades without proper validation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any existing upgrade validation logic related to packed models
rg -A 5 "is_packed.*upgrade"
ast-grep --pattern 'fn $upgrade_fn($_, $_) {
$$$
is_packed
$$$
}'
Length of output: 104
Script:
#!/bin/bash
# Let's search more broadly for packed model handling
rg -A 10 "is_packed"
# Also search for upgrade-related functionality
rg -A 10 "upgrade.*model"
# Look for model validation logic
ast-grep --pattern 'fn validate($$$) {
$$$
}'
Length of output: 34786
Script:
#!/bin/bash
# Let's look for model upgrade validation logic in the core tests
rg -A 10 "test.*upgrade.*model.*bad|test.*model.*upgrade.*invalid" crates/dojo/core-cairo-test/
# Search for model upgrade implementation details
ast-grep --pattern 'fn upgrade_model($$$) {
$$$
}'
# Look for packed model specific validation
rg -A 5 "packed.*model.*valid|valid.*packed.*model"
Length of output: 1176
Script:
# Let's check how model upgrades are validated in the world contract
rg -A 15 "Invalid new schema.*upgrade" crates/dojo/core/src/world/
# Look for model schema validation logic
ast-grep --pattern 'fn validate_schema($$$) {
$$$
}'
# Search for packed model specific checks during upgrades
rg -B 5 -A 10 "is_packed.*validate|validate.*is_packed" crates/dojo/core/
Length of output: 1492
crates/dojo/core-cairo-test/src/tests/world/event.cairo (3)
10-46
: Ohayo, sensei! Excellent test coverage with event structs!
The event structs are well-designed to test various upgrade scenarios, including:
- Field removal (
FooEventMemberRemoved
) - Field addition and removal (
FooEventMemberAddedButRemoved
) - Field movement (
FooEventMemberAddedButMoved
) - Valid field addition (
FooEventMemberAdded
)
This comprehensive set ensures robust testing of the upgrade constraints.
48-98
: Ohayo! Comprehensive permission testing for event registration!
The test cases effectively validate:
- Successful registration by namespace owner
- Failed registration attempt by namespace writer
- Proper event emission and ownership assignment
The permission checks align well with the security requirements.
99-214
: Ohayo! Excellent coverage of upgrade constraints!
The upgrade tests thoroughly validate the PR's key requirements:
- Same layout type must be maintained
- Existing fields cannot be changed/moved
- New fields can only be appended at the end
Each constraint is tested with both positive and negative cases.
crates/dojo/core-cairo-test/src/tests/world/model.cairo (1)
58-120
: Ohayo, sensei! Registration tests look comprehensive!
The test cases effectively validate model registration with proper permission checks and name validation.
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (5)
60-100
: Well-structured test coverage for upgrade scenarios
Ohayo sensei! The test cases effectively cover both successful and failed upgrade scenarios, including:
- Upgrades from world
- Direct upgrades
- Invalid provider upgrades
102-157
: Well-structured invalid model test contracts
Ohayo sensei! The invalid model contracts are well-organized and provide good test coverage for error scenarios.
159-361
: Excellent security coverage in namespace management tests
Ohayo sensei! The test suite demonstrates excellent security considerations:
- Proper access control validation
- Protection against malicious contracts
- Comprehensive event validation
- Edge case handling for unregistered namespaces
This thorough testing helps ensure the security of the upgrade system.
71-72
:
Fix type mismatch in assertion
Ohayo sensei! The assertion compares a felt252
with a string literal which could lead to unexpected behavior.
Apply this diff to fix the comparison:
- assert(quantum_dispatcher.plz_more_tps() == 'daddy', 'quantum leap failed');
+ assert(quantum_dispatcher.plz_more_tps() == 123_felt252, 'quantum leap failed'); // Replace with expected felt252 value
Likely invalid or redundant comment.
40-42
:
Fix type mismatch in return value
Ohayo sensei! The function returns a string literal where a felt252
is expected. This could lead to runtime issues.
Apply this diff to fix the type:
fn plz_more_tps(self: @ContractState) -> felt252 {
- 'daddy'
+ 123_felt252 // Replace with appropriate felt252 value
}
Likely invalid or redundant comment.
crates/dojo/world/src/contracts/abigen/model.rs (3)
Line range hint 627-637
: Schema method update looks clean, sensei!
The return type change from Ty
to Struct
is consistent with the ModelDef changes and maintains the established pattern for contract methods.
Line range hint 732-742
: ModelContractReader schema changes are consistent!
The schema method changes mirror those in ModelContract, maintaining symmetry between the two implementations.
Line range hint 176-217
: Ohayo sensei! The ModelDef changes look good.
The removal of versioning and the schema type change from Ty
to Struct
aligns well with the PR objectives. The serialization/deserialization logic has been properly updated to handle these changes.
Let's verify no versioning references remain:
✅ Verification successful
Let me verify the remaining references with more context to ensure they're not problematic.
Let me verify the remaining version references in the model plugin code to ensure they're just test cases.
Let me try one more search with a different path pattern:
Ohayo sensei! Based on the verification results, I can now provide a conclusive response:
The version removal changes are safe and properly implemented.
The remaining version references are only in test files (plugin_test_data/model
) which are specifically designed to test error handling for invalid version attributes. These test cases ensure the model plugin correctly rejects invalid version usage, which is exactly what we want.
The only other version reference is in a comment about Torii versioning, which is unrelated to the model versioning being removed.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version references in model-related files
# Expect: No occurrences of version in model definitions
rg -i "version.*model"
Length of output: 453
Script:
#!/bin/bash
# Get context around version references in model files
rg -B 3 -A 3 -i "version.*model"
# Check for any version-related structs or fields in model.rs
ast-grep --pattern 'struct $_ {
$$$
version: $_,
$$$
}'
# Check model plugin for version handling
fd "model.rs" --exec cat {}
Length of output: 135533
Script:
# Check model plugin implementation for version handling
rg -B 2 -A 2 "version" crates/dojo/lang/src/plugin/model.rs
# Check if there are any version-related structs or fields in the model plugin
ast-grep --pattern 'struct $_ {
$$$
version: $_,
$$$
}'
Length of output: 200
Script:
# Check for version references in model-related files
fd "model.rs" --exec rg -B 2 -A 2 "version" {}
# Check test data for version references
rg -B 2 -A 2 "version" crates/dojo/lang/src/plugin_test_data/model
Length of output: 3226
crates/dojo/core/src/world/world_contract.cairo (4)
42-45
: LGTM! Import changes align with new resource management approach.
The updated imports support the new resource management system, particularly the Layout
and dispatcher types needed for upgradability checks.
975-1010
: LGTM! Robust resource upgradability checks.
The assert_resource_upgradability
function implements essential checks:
- Layout type consistency (Struct/Fixed)
- Existing field preservation
- New field append-only policy
Line range hint 540-615
: Verify model upgrade compatibility checks.
Similar to events, model upgrades now include proper validation. The implementation correctly prevents breaking changes in existing fields.
#!/bin/bash
# Description: Check if all model contracts implement IStoredResource interface
# Expected: All model contracts should have layout() and schema() methods
# Search for model contract implementations
ast-grep --pattern 'impl $_ of IStoredResource<$_> {
fn layout($_, $_) -> Layout {
$$$
}
fn schema($_, $_) -> Schema {
$$$
}
}'
Line range hint 436-511
: Verify event upgrade compatibility checks.
The event upgrade process now includes proper validation through assert_resource_upgradability
. However, we should verify that all event contracts implement the required interfaces.
✅ Verification successful
Let me search for event-related code patterns to verify the implementation requirements. The previous pattern might have been too specific, so I'm broadening the search to find event contracts and their implementations.
Ohayo! Let me try again without the file type restriction, sensei! This should help us find the event contracts and their implementations to verify the compatibility checks.
Event contracts properly implement required interfaces
Ohayo sensei! After analyzing the codebase, I can confirm that event contracts are properly implementing the required interfaces. The verification shows:
- Events automatically implement
IDeployedResource
through the event component macro (seecrates/dojo/core/src/event/component.cairo
) - Events implement
IStoredResource
as shown in test implementations (e.g.,crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
) - The upgrade process in
world_contract.cairo
correctly validates both interfaces throughassert_resource_upgradability
The implementation is consistent and safe across the codebase.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if all event contracts implement IStoredResource interface
# Expected: All event contracts should have layout() and schema() methods
# Search for event contract implementations
ast-grep --pattern 'impl $_ of IStoredResource<$_> {
fn layout($_, $_) -> Layout {
$$$
}
fn schema($_, $_) -> Schema {
$$$
}
}'
Length of output: 145
Script:
#!/bin/bash
# Let's try a different approach to find event contracts and their implementations
# First, find all event contracts
rg -A 5 "contract\s+\w+Event\s+" --type cairo
# Also search for IStoredResource trait implementations
rg -A 5 "impl.*IStoredResource" --type cairo
# And check for any event-related interfaces
rg -A 5 "trait\s+I\w*Event\w*\s+" --type cairo
Length of output: 233
Script:
#!/bin/bash
# Let's try without specifying file type since cairo isn't recognized
# Find all event contracts
rg -A 5 "contract\s+\w+Event\s+"
# Search for IStoredResource trait implementations
rg -A 5 "impl.*IStoredResource"
# Check for event-related interfaces
rg -A 5 "trait\s+I\w*Event\w*\s+"
# Also search for deployed event references
rg -A 5 "IDeployedResource"
Length of output: 18981
// Ensures the generated contract has a unique classhash, using | ||
// a hardcoded hash computed on model and member names. | ||
#[external(v0)] | ||
fn ensure_unique(self: @ContractState) { | ||
let _hash = $unique_hash$; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Documentation needed for unique hash computation, sensei!
The unique hash is computed using Poseidon hash with the following inputs:
- A flag indicating if the model is packed (0 or 1)
- The model name as a bytearray hash
- For each member: Poseidon hash of (member_name_hash, member_type_hash)
This hash is critical for model upgradability as it ensures:
- Different model names produce different hashes
- Changes to member names or types produce different hashes
- Packed vs unpacked models produce different hashes
Please add this documentation to help other developers understand the hash computation and its role in model upgrades.
🔗 Analysis chain
Consider documenting the hash computation, sensei!
While the unique hash implementation is a great addition for preventing accidental deployments of incompatible models, it would be helpful to document:
- How the hash is computed from model and member names
- When and how this uniqueness check is used during upgrades
Let's check if this is documented elsewhere:
Let me search for more specific information about the unique hash implementation.
Let me check the macro implementation to understand how the unique hash is computed.
Let me check the actual implementation of the hash computation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for documentation about the unique hash computation
rg -g '!*.cairo' -g '*.md' -i "model.*hash|unique.*hash|classhash"
Length of output: 953
Script:
#!/bin/bash
# Search for unique hash implementation details in model-related files
rg -g '*.cairo' -B 5 -A 5 "unique.*hash|ensure_unique"
# Also check for any comments or documentation in the model patch file
cat crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
Length of output: 8091
Script:
#!/bin/bash
# Search for the macro that processes the model and generates the unique hash
rg -g '*.rs' -B 5 -A 5 "unique.*hash|ensure_unique" crates/dojo/lang/src/
# Also check for any documentation in the Rust implementation
fd -e rs . crates/dojo/lang/src/ -x cat {} | rg -B 5 -A 5 "model.*hash|unique.*hash"
Length of output: 11929
Script:
#!/bin/bash
# Check the implementation of compute_unique_hash function
cat crates/dojo/lang/src/attribute_macros/element.rs
Length of output: 6936
diagnostics.push(PluginDiagnostic { | ||
stable_ptr: arg.stable_ptr().0, | ||
message: format!( | ||
"Unexpected parameter {} for {attribute_name}.", | ||
arg.as_syntax_node().get_text(db) | ||
), | ||
severity: Severity::Warning, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using Error severity for unexpected parameters, sensei!
While the error handling implementation is good, unexpected parameters in event definitions could lead to silent failures or misconceptions about the event's behavior. Consider changing the severity from Warning
to Error
to ensure these issues are caught early in development.
- severity: Severity::Warning,
+ severity: Severity::Error,
📝 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.
diagnostics.push(PluginDiagnostic { | |
stable_ptr: arg.stable_ptr().0, | |
message: format!( | |
"Unexpected parameter {} for {attribute_name}.", | |
arg.as_syntax_node().get_text(db) | |
), | |
severity: Severity::Warning, | |
}); | |
diagnostics.push(PluginDiagnostic { | |
stable_ptr: arg.stable_ptr().0, | |
message: format!( | |
"Unexpected parameter {} for {attribute_name}.", | |
arg.as_syntax_node().get_text(db) | |
), | |
severity: Severity::Error, | |
}); |
21369dc
to
c0eafe1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (14)
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (1)
59-65
: Clean interface separation, sensei!The three-tier event implementation (Deployed, Stored, and General) provides a solid foundation for managing event upgradability while maintaining clear separation of concerns.
Consider documenting the responsibility of each interface in the module-level documentation to help other developers understand when to use each one.
crates/dojo/core/src/model/model.cairo (1)
1-3
: Ohayo! The import changes align well with the upgradability requirements, sensei!The switch from
Ty
toStruct
provides better type safety and validation capabilities for ensuring layout compatibility during model upgrades.The use of
Struct
type will help enforce the PR's upgrade conditions by providing stronger type checking for layout modifications.crates/torii/types-test/src/contracts.cairo (1)
Line range hint
119-132
: Ohayo! A few suggestions to enhance the delete implementation, sensei!The delete implementation has several areas that could be improved:
- Consider adding existence checks before deletion
- The assumption that
subrecord_id = record_id + 1
seems brittle- Missing error handling for failed operations
- Consider emitting a deletion event for consistency with create
Here's a suggested improvement:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); + // Validate record exists + assert(world.model_exists<Record>(record_id), 'Record does not exist'); let record: Record = world.read_model(record_id); let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; + // Read subrecord_id from record if available let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); world.erase_model(@record); world.erase_model(@record_sibling); world.erase_model(@subrecord); + + // Emit deletion event for tracking + world.emit_event( + @RecordDeleted { record_id } + ); }You'll also need to add the event definition:
#[derive(Drop, Serde, starknet::Event)] #[dojo::event] struct RecordDeleted { #[key] record_id: u32, }crates/dojo/lang/src/attribute_macros/element.rs (2)
86-107
: Ohayo sensei! Please add documentation for the new hash function.The implementation looks solid and aligns well with the upgradability checking requirements. However, it would be beneficial to add documentation explaining:
- The purpose of this hash computation
- How it contributes to upgradability checking
- The significance of the packed flag
- The format of the resulting hash
Add documentation like this:
+/// Computes a unique hash for a struct based on its name, packing status, and member types. +/// This hash is used to verify upgradability by ensuring that new versions maintain +/// compatibility with existing field layouts. +/// +/// # Arguments +/// +/// * `db` - The syntax database +/// * `element_name` - Name of the struct +/// * `is_packed` - Whether the struct uses packed layout +/// * `members` - List of struct members +/// +/// # Returns +/// +/// A Felt containing the unique hash for this struct layout pub fn compute_unique_hash(
Line range hint
1-107
: Ohayo sensei! The architectural changes align perfectly with the PR objectives!The removal of versioning code and introduction of the
compute_unique_hash
function creates a more robust system for checking model and event upgradability. The hash-based approach ensures that:
- Layout type consistency is maintained
- Existing fields remain unchanged
- New fields can only be appended
This is a cleaner solution compared to the previous version-based approach.
crates/dojo/lang/src/attribute_macros/model.rs (1)
155-156
: Nice addition of packed model detection, sensei!The
is_packed
flag is crucial for model upgradability as packed and unpacked models have different layouts. This distinction helps prevent incompatible upgrades between different layout types.Consider documenting this constraint in the model's metadata or schema to make it explicit for developers attempting upgrades.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (2)
62-62
: Fix typo in assertion message.Ohayo! There's a typo in the assertion message: 'no event)' appears with an extra parenthesis.
- assert(event.is_some(), 'no event)'); + assert(event.is_some(), 'no event');Also applies to: 114-114
99-163
: Consider extracting common event verification logic.Ohayo, sensei! The event verification logic is duplicated between
test_upgrade_event
andtest_upgrade_event_from_event_owner
. Consider extracting it into a helper function.fn verify_event_upgrade( world: IWorldDispatcher, event: Option<world::Event> ) { assert(event.is_some(), 'no event'); if let world::Event::EventUpgraded(event) = event.unwrap() { assert( event.selector == Event::<FooEventMemberAdded>::selector(DOJO_NSH), 'bad model selector' ); assert( event.class_hash == e_FooEventMemberAdded::TEST_CLASS_HASH.try_into().unwrap(), 'bad model class_hash' ); assert( event.address != core::num::traits::Zero::<ContractAddress>::zero(), 'bad model address' ); } else { core::panic_with_felt252('no EventUpgraded event'); } }crates/dojo/core-cairo-test/src/tests/world/model.cairo (2)
11-56
: Ohayo, sensei! Model structs are well-structured for testing upgrade scenariosThe test models effectively cover various upgrade scenarios including layout changes, field modifications, and field additions. Consider adding doc comments to explain the purpose of each test model.
Add documentation comments like this:
+/// Tests model upgrade with incompatible layout type #[derive(Introspect, Copy, Drop, Serde)] #[dojo::model] pub struct FooModelBadLayoutType {
121-185
: Ohayo, sensei! Model upgrade tests look solidThe tests thoroughly validate the upgrade process and event emission. Consider adding a test for concurrent upgrades to ensure thread safety.
Add a test like:
#[test] fn test_concurrent_model_upgrades() { let world = deploy_world_for_model_upgrades(); // Simulate concurrent upgrades and verify last upgrade wins // ... }crates/dojo/core-cairo-test/src/tests/world/contract.cairo (3)
8-20
: Consider consolidating duplicate contract patternsOhayo sensei! I notice similar patterns across multiple contract modules where each implements a metadata-related trait with minimal variation. Consider consolidating these into a more maintainable structure.
Consider using a macro to generate these contract implementations to reduce code duplication. For example:
#[macro_export] macro_rules! implement_metadata_contract { ($mod_name:ident, $dojo_name:expr) => { #[starknet::contract] mod $mod_name { #[storage] struct Storage {} #[abi(embed_v0)] impl MetadataImpl of super::IMetadataOnly<ContractState> { fn dojo_name(self: @ContractState) -> ByteArray { $dojo_name } } } }; }This would allow you to define contracts more concisely:
implement_metadata_contract!(invalid_model, "invalid_model"); implement_metadata_contract!(invalid_model_world, "invalid_model_world");Also applies to: 27-58, 108-118, 121-131, 134-144, 147-157
164-164
: Consider using named constants for test addressesOhayo sensei! The test addresses are currently hardcoded using
starknet::contract_address_const
. Consider defining these as named constants at the module level for better maintainability and readability.const BOB_ADDRESS: felt252 = 0xb0b; const ALICE_ADDRESS: felt252 = 0xa11ce; const MALICIOUS_CONTRACT_ADDRESS: felt252 = 0xdead; // Then use them in tests let bob = starknet::contract_address_const::<BOB_ADDRESS>();Also applies to: 200-200, 217-217, 242-242, 258-258, 301-301, 334-334, 349-349
171-171
: Consider creating a test helper for event cleanupOhayo sensei! The
drop_all_events
call is repeated in multiple test functions. Consider wrapping this in a test helper that combines setup and event cleanup.fn setup_test_with_clean_events() -> IWorldDispatcher { let world = deploy_world(); drop_all_events(world.contract_address); world }Also applies to: 268-268
crates/dojo/world/src/contracts/abigen/model.rs (1)
Ohayo sensei! Schema type inconsistencies detected across the codebase
The change from
Ty
toStruct
inModelDef
requires corresponding updates in several other files that still use theTy
type for schema:
crates/torii/core/src/sql/mod.rs
crates/torii/core/src/sql/cache.rs
crates/torii/grpc/src/types/mod.rs
crates/dojo/types/src/schema.rs
These files need to be updated to maintain consistency with the new schema type changes in
ModelDef
.🔗 Analysis chain
Line range hint
176-217
: LGTM! Changes align with versioning removal.Ohayo sensei! The removal of the version field and the schema type change from
Ty
toStruct
align perfectly with the PR objectives. Let's verify that all model definitions in the codebase are compatible with this change.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify model definitions in the codebase are compatible with the new schema type. # Test: Search for model definitions that might still use the old Ty type rg -A 5 'schema:\s*Ty'Length of output: 1554
Script:
#!/bin/bash # Let's check if these files have been updated in the PR git diff origin/main -- crates/torii/core/src/sql/mod.rs crates/torii/core/src/sql/cache.rs crates/torii/grpc/src/types/mod.rs crates/dojo/types/src/schema.rs # Also check for any pending changes in the current branch git diff -- crates/torii/core/src/sql/mod.rs crates/torii/core/src/sql/cache.rs crates/torii/grpc/src/types/mod.rs crates/dojo/types/src/schema.rsLength of output: 309
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (42)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(2 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (24)
- Cargo.toml
- crates/dojo/core-cairo-test/src/lib.cairo
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/component.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/Cargo.toml
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/world/src/contracts/model.rs
- examples/spawn-and-move/dojo_dev.toml
🔇 Additional comments (34)
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (2)
77-82
: Clever unique hash enforcement mechanism, sensei!
The hardcoded hash based on event and member names effectively prevents accidental or malicious event collisions during upgrades.
Let's verify the uniqueness of these hashes across all events:
#!/bin/bash
# Extract and compare unique hashes across all event implementations
rg -A 1 "fn ensure_unique.*\{" | rg "let _hash = .*;" | sort | uniq -d
22-28
: Ohayo! Schema type enforcement looks solid, sensei!
The stricter return type and runtime check ensure events maintain their structure, which is crucial for the upgradability requirements.
Let's verify no events are using non-struct types:
crates/dojo/core/src/lib.cairo (3)
12-13
: Ohayo! Clean module addition, sensei!
The new component
module under event
follows the established module structure pattern nicely.
25-30
: Verify the integration of new resource interfaces, sensei!
The new resource interfaces (IDeployedResource
and IStoredResource
) are crucial for the upgradability checks. Let's ensure they're properly integrated.
32-32
: Ohayo! Please verify upgrade rule enforcement in comparison traits.
The StructCompareTrait
and LayoutCompareTrait
exports are crucial for implementing the upgrade conditions. Let's verify they properly enforce:
- Same layout type (Struct/Fixed) requirement
- No changes to existing fields
- New fields only allowed at the end
Also applies to: 35-35
✅ Verification successful
Let me search for the trait definitions since the implementations weren't found.
Let me search for the Layout type and any comparison traits for it.
Let me check the layout module for the implementation details.
Ohayo! The upgrade rules are properly enforced, sensei!
The verification shows that both traits correctly enforce the upgrade rules:
-
StructCompareTrait
enforces:- Same name and attributes check (
self.name != old.name || self.attrs != old.attrs
) - No removal of existing fields (
(*self.children).len() < (*old.children).len()
) - No changes to existing fields (
*old.children[i] != *self.children[i]
) - New fields only at the end (loop checks up to old length only)
- Same name and attributes check (
-
LayoutCompareTrait
enforces:- Same layout type requirement through
is_same_type_of
method - Matches Fixed/Struct/Tuple/Array/ByteArray/Enum types
- Same layout type requirement through
The implementation is used in assert_resource_upgradability
which validates both layout and schema upgrades before allowing any resource upgrade.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the implementation of upgrade rules in comparison traits
# Expected: Find trait implementations with upgrade rule checks
echo "Checking StructCompareTrait implementation..."
ast-grep --pattern 'impl StructCompareTrait for $_ {
$$$
}'
echo "Checking LayoutCompareTrait implementation..."
ast-grep --pattern 'impl LayoutCompareTrait for $_ {
$$$
}'
Length of output: 329
Script:
#!/bin/bash
# Search for trait definitions
echo "Searching for StructCompareTrait definition..."
rg "trait StructCompareTrait" -A 10
echo "Searching for LayoutCompareTrait definition..."
rg "trait LayoutCompareTrait" -A 10
# Search in introspect module
echo "Checking introspect module contents..."
fd "introspect.cairo" --exec cat {}
Length of output: 13799
Script:
#!/bin/bash
# Search for Layout type definition and comparison traits
echo "Searching for Layout type..."
fd "Layout" --exec rg -l "enum Layout" {}
echo "Checking Layout file contents..."
fd "Layout" --exec cat {}
echo "Searching for LayoutCompareTrait..."
rg -g "!target" "LayoutCompareTrait"
Length of output: 654
Script:
#!/bin/bash
echo "Checking layout.cairo contents..."
cat crates/dojo/core/src/meta/layout.cairo
echo "Checking world_contract.cairo for usage..."
cat crates/dojo/core/src/world/world_contract.cairo
Length of output: 49230
crates/dojo/core/src/model/model.cairo (2)
91-93
: Clean implementation, sensei!
The schema implementation correctly delegates to ModelDefinition, maintaining simplicity.
Line range hint 108-116
: ModelDef construction updated correctly to remove versioning!
The removal of the version field aligns with the PR objectives to eliminate versioning management.
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (3)
84-89
: Clean trait separation for deployed and stored models, sensei!
The split between deployed and stored model implementations provides better separation of concerns and clearer interfaces.
110-115
: Referencing existing documentation request.
The previous review comment about documenting the unique hash computation is still valid and applicable here.
33-39
: LGTM! Enhanced type safety for model schema, sensei!
The schema function now properly enforces that models must be structs, which is essential for the upgradability checks.
Let's verify no models are using non-struct types:
crates/torii/types-test/src/contracts.cairo (1)
112-113
: Ohayo! Clean method chaining implementation, sensei!
The method chaining pattern for emit_event
improves code readability while maintaining the same functionality.
crates/dojo/lang/src/attribute_macros/event.rs (3)
20-20
: Ohayo! The import looks good, sensei!
The addition of compute_unique_hash
aligns well with the PR's objective of implementing upgradability checks for events.
127-127
: Verify the EVENT_PATCH template usage, sensei!
The unique hash is now included in the event patch, but we should verify:
- How this hash is used in the EVENT_PATCH template
- Whether it properly enforces the upgradability constraints mentioned in the PR objectives
#!/bin/bash
# Description: Check the EVENT_PATCH template content and usage
echo "Checking EVENT_PATCH content:"
cat crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
echo "\nChecking usage of unique_hash in patch files:"
rg "unique_hash" --type cairo
114-116
: Ohayo! Let's enhance the documentation and verification, sensei!
The hash computation is crucial for upgradability checks, but a few improvements would help:
- Document the purpose of the
false
flag parameter - Add a comment explaining how this hash ensures upgradability constraints
- Consider adding validation to ensure the hash meets expected format/requirements
✅ Verification successful
Ohayo! The hash computation is well-implemented, sensei!
After reviewing the implementation, the false
parameter in compute_unique_hash
is actually well-defined and serves a clear purpose. Looking at the source code:
- The
false
parameter indicates this is an event (not a packed struct), which is correct - The hash computation is properly implemented to ensure upgradability constraints by:
- Using the event name and member information
- Including member types and names in the hash calculation
- Using Poseidon hash for cryptographic uniqueness
The implementation is secure and follows best practices. No changes needed! 🎋
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the compute_unique_hash function is documented in the codebase
rg -A 5 "compute_unique_hash" --type rust
Length of output: 2832
Script:
#!/bin/bash
# Let's search for the compute_unique_hash function definition and its usages
ast-grep --pattern 'fn compute_unique_hash($$$) { $$$ }'
# Also search for any comments or documentation about this function
rg -B 3 "compute_unique_hash" --type rust
Length of output: 1865
Script:
#!/bin/bash
# Let's check if there are any tests or examples using this function
fd -e rs -x rg -l "compute_unique_hash" {}
Length of output: 193
Script:
#!/bin/bash
# Let's check the module where this function might be defined
rg "mod.*\{" crates/dojo/lang/src/attribute_macros/event.rs
Length of output: 61
Script:
#!/bin/bash
# Let's look at the entire event.rs file to understand the context
cat crates/dojo/lang/src/attribute_macros/event.rs
Length of output: 6117
Script:
#!/bin/bash
# Let's check the element.rs file where compute_unique_hash is defined
cat crates/dojo/lang/src/attribute_macros/element.rs
Length of output: 6936
Script:
#!/bin/bash
# Let's also check if there are any tests for this functionality
fd test -e rs -x rg -l "compute_unique_hash" {}
Length of output: 49
Script:
#!/bin/bash
# Let's check if there are any comments about hash computation in the model implementation
rg -B 5 "compute_unique_hash.*is_packed" --type rust
Length of output: 609
crates/dojo/lang/src/attribute_macros/element.rs (1)
7-7
: Ohayo sensei! The import changes look good!
The new imports are well-organized and properly support the hash computation functionality introduced in this PR.
Also applies to: 12-13
crates/dojo/core/src/meta/introspect.cairo (2)
38-39
: Ohayo! The trait generation looks good, sensei!
The #[generate_trait]
attribute and trait implementation declaration follow Cairo best practices.
40-61
: 🛠️ Refactor suggestion
The upgrade validation implementation needs additional safeguards, sensei!
While the implementation correctly ensures that existing fields remain unchanged and new fields can only be appended, there are a few concerns:
- The implementation doesn't explicitly validate the layout type (Struct/Fixed) as mentioned in the PR objectives
- The member comparison at line 54 uses exact matching, but we should document this strict behavior
Consider applying these improvements:
fn is_an_upgrade_of(self: @Struct, old: @Struct) -> bool {
if self.name != old.name
|| self.attrs != old.attrs
|| (*self.children).len() < (*old.children).len() {
return false;
}
+ // Validate that all existing fields remain unchanged
+ // New fields can only be appended at the end
let mut i = 0;
loop {
if i >= (*old.children).len() {
break true;
}
if *old.children[i] != *self.children[i] {
break false;
}
i += 1;
}
}
Let's verify the usage of this implementation:
crates/dojo/lang/src/attribute_macros/model.rs (3)
18-18
: Ohayo! Import changes look good, sensei!
The addition of compute_unique_hash
import aligns well with the PR's objective of implementing model upgradability checks.
180-180
: Hash interpolation is perfectly placed, sensei!
The addition of unique_hash
to the interpolation map ensures the hash is available in generated code for upgradability checks.
160-163
: Unique hash computation looks solid but needs formatting adjustment, sensei!
The hash computation correctly incorporates model type, packed status, and members for upgradability checks. However, the indentation could be more consistent with the surrounding code.
Consider adjusting the indentation to match the surrounding code style:
- let unique_hash =
- compute_unique_hash(db, &model_type, is_packed, &struct_ast.members(db).elements(db))
- .to_string();
+ let unique_hash = compute_unique_hash(
+ db,
+ &model_type,
+ is_packed,
+ &struct_ast.members(db).elements(db)
+ ).to_string();
Let's verify the hash computation implementation:
crates/dojo/core-cairo-test/src/tests/world/event.cairo (3)
10-46
: LGTM! Well-structured event definitions for upgrade testing scenarios.
Ohayo, sensei! The event structs are thoughtfully designed to test different upgrade scenarios:
FooEventMemberRemoved
: Tests field removalFooEventMemberAddedButRemoved
: Tests field addition and removalFooEventMemberAddedButMoved
: Tests field movementFooEventMemberAdded
: Base event structure
48-97
: LGTM! Comprehensive event registration tests.
The test cases effectively verify:
- Event registration by namespace owner
- Permission checks for writers
- Event emission and property validation
216-277
: LGTM! Thorough permission and edge case testing.
Ohayo! The test suite effectively covers:
- Permission checks for writers and random accounts
- Unregistered namespace handling
- Malicious contract interactions
crates/dojo/core-cairo-test/src/tests/world/model.cairo (2)
58-120
: Ohayo, sensei! Comprehensive model registration test coverage
The registration tests effectively validate:
- Ownership requirements
- Name validation rules
- Permission checks
- Event emission
Note: There's an existing comment about the typo in assertion messages.
187-297
: Ohayo, sensei! Excellent error case coverage for model upgrades
The tests comprehensively validate all upgrade constraints mentioned in PR objectives:
- Layout type consistency
- Field preservation
- Field ordering
- Permission requirements
- Security against malicious contracts
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (1)
159-361
: LGTM! Comprehensive test coverage
Ohayo sensei! The test suite provides excellent coverage of various scenarios including:
- Contract deployment permissions
- Upgrade permissions
- Namespace ownership
- Security checks for malicious contracts
- Event verification
The tests are well-structured and cover both happy and error paths.
crates/dojo/world/src/contracts/abigen/model.rs (2)
Line range hint 627-636
: LGTM! Schema method return type updated consistently.
The schema method's return type change from Ty
to Struct
maintains consistency with the ModelDef changes.
Line range hint 732-741
: LGTM! Schema method return type updated consistently.
The schema method's return type change from Ty
to Struct
maintains consistency with both ModelDef and ModelContract changes.
crates/dojo/core/src/world/world_contract.cairo (6)
42-45
: LGTM! Import changes align with new functionality.
The new imports from dojo::meta
provide the necessary types and traits for implementing resource upgradability checks.
Line range hint 429-433
: Consistent dispatcher type updates across resource handlers.
The change from specific dispatchers (IEventDispatcher
, IModelDispatcher
, IContractDispatcher
) to the unified IDeployedResourceDispatcher
improves code consistency and maintainability.
Also applies to: 475-479, 533-537, 579-583, 658-662, 713-717
501-504
: LGTM! Strategic placement of upgradability check.
The assert_resource_upgradability
check is correctly placed before updating the resource in storage, ensuring that invalid upgrades are rejected early.
1053-1088
: Ohayo, sensei! Robust implementation of resource upgradability checks.
The implementation aligns perfectly with the PR objectives by enforcing:
- Layout type consistency (Struct or Fixed)
- Preservation of existing fields
- Append-only new fields
The error messages are descriptive and will help developers understand upgrade constraints.
1106-1108
: Consistent error message formatting for resource types.
The error message formatting is consistent across different resource types (contract, event, model), improving the debugging experience.
Also applies to: 1112-1114, 1118-1120
1137-1139
: Consider handling non-Dojo callers in permission checks.
This comment was previously made and is still valid. The code assumes the caller is a Dojo contract when formatting error messages, which could cause issues with non-Dojo callers.
/// Returns the schema of the model. | ||
fn schema() -> Ty; | ||
fn schema() -> Struct; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Ohayo! We need to update test data implementations, sensei!
The schema return type change from Ty
to Struct
needs attention in test files. Found:
- Core implementations in
definition.cairo
andevent.cairo
are correctly usingStruct
- Test data files still use the old
Ty
return type:plugin_test_data/model
: 11 implementationsplugin_test_data/event
: 3 implementations
The patch files show the correct implementation pattern using Struct
, but test data hasn't been updated yet.
🔗 Analysis chain
Let's verify the impact of schema return type change, sensei!
The change from Ty
to Struct
return type is correct, but we should verify all implementations.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining implementations using the old Ty return type
ast-grep --pattern 'fn schema() -> Ty'
# Search for all schema implementations to ensure they're updated
rg -l "fn schema\(\)"
Length of output: 402
Script:
#!/bin/bash
# Let's check the actual implementation of schema() in these files
rg "fn schema\(\)" -A 5 crates/dojo/core/src/model/definition.cairo crates/dojo/core/src/event/event.cairo
# Also check the test data and patches to see their implementations
rg "fn schema\(\)" -A 5 crates/dojo/lang/src/plugin_test_data/event crates/dojo/lang/src/plugin_test_data/model crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
Length of output: 8917
c0eafe1
to
f6cff5f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (11)
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (2)
59-65
: Clean interface separation, sensei!The split into Deployed, Stored, and base Event implementations provides a clear separation of concerns and better modularity. This structure will make upgrades more manageable.
Consider documenting the responsibility of each interface in the module-level documentation to help other developers understand when to use each one.
77-82
: The unique hash implementation needs more context, sensei!While the unique hash implementation is a good addition for preventing collisions, it would benefit from documentation explaining:
- How the hash is computed
- Why it's necessary for upgradability
- What developers should consider when modifying events
Add documentation above the
ensure_unique
function:// Ensures the generated contract has a unique classhash, using // a hardcoded hash computed on event and member names. + /// Ensures uniqueness of this event contract by incorporating a hash + /// computed from the event name and its member names. + /// This prevents accidental collisions during upgrades and ensures + /// each event version has a distinct identity. #[external(v0)] fn ensure_unique(self: @ContractState) {crates/torii/types-test/src/contracts.cairo (1)
Line range hint
117-131
: Ohayo sensei! A few concerns about the delete implementation.The delete implementation has several potential issues:
- The
subrecord_id
calculation (record_id + 1
) assumes sequential IDs, which might not always be true.- There's no error handling for non-existent records.
- Consider emitting a deletion event for tracking purposes.
Here's a suggested improvement:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); - let record: Record = world.read_model(record_id); - let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; - let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); + // Check if record exists + match world.try_read_model::<Record>(record_id) { + Option::Some(record) => { + let record_sibling: RecordSibling = world.read_model(record_id); + + // Find associated subrecord + let subrecords = world.get_models::<Subrecord>() + .filter(|s| s.record_id == record_id); + + // Perform deletion + world.erase_model(@record); + world.erase_model(@record_sibling); + for subrecord in subrecords { + world.erase_model(@subrecord); + } + + // Emit deletion event + world.emit_event( + @RecordDeleted { record_id } + ); + }, + Option::None => { + panic_with_felt252('Record not found') + } + } - world.erase_model(@record); - world.erase_model(@record_sibling); - world.erase_model(@subrecord); }Don't forget to add the deletion event structure:
#[derive(Drop, Serde, starknet::Event)] #[dojo::event] struct RecordDeleted { #[key] record_id: u32, }crates/dojo/lang/src/attribute_macros/model.rs (2)
18-19
: Ohayo sensei! Nice modularization of hash computation logic.The extraction of
compute_unique_hash
into a shared module is a good architectural decision, as it enables consistent hash generation across both models and events.
180-180
: Excellent integration of unique hash in model generation.The unique hash is correctly integrated into the RewriteNode interpolation, which will be used to enforce upgradability constraints.
Consider documenting the hash format and its role in upgradability checks in the code comments to help future maintainers understand the importance of this value.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (3)
48-82
: Consider enhancing test assertions, sensei!The test verifies basic registration functionality, but consider adding assertions for:
- Event schema validation
- Resource name format validation
103-167
: Consider improving error messages for better debuggingOhayo! The error messages in assertions could be more descriptive. For example:
- assert(event.is_some(), 'no event)'); + assert(event.is_some(), 'Event emission missing after upgrade');
169-287
: Consider grouping related test cases, sensei!The error case tests could be organized into logical groups using nested modules:
- Layout validation tests
- Permission tests
- Schema validation tests
This would improve test organization and readability.
Example structure:
mod layout_tests { #[test] fn test_upgrade_event_with_bad_layout_type() { // ... existing code } } mod permission_tests { #[test] fn test_upgrade_event_from_event_writer() { // ... existing code } }crates/dojo/core-cairo-test/src/tests/world/entities.cairo (1)
248-248
: Consistent dispatcher usage looks good, but could be improved, sensei!The consistent usage of
world.dispatcher
improves code clarity by making it explicit that we're working with the dispatcher interface. However, there's a repetitive pattern that could be simplified.Consider modifying the
deploy_world()
helper to return the dispatcher directly, eliminating the need for the repetitive assignment:// In the test helpers module -fn deploy_world() -> World { +fn deploy_world() -> IWorldDispatcher { - // existing implementation + let world = // existing implementation + world.dispatcher } // In test functions -let world = deploy_world(); -let world = world.dispatcher; +let world = deploy_world();This would:
- Reduce code repetition
- Make the interface usage more explicit
- Prevent potential mistakes where someone forgets to get the dispatcher
Also applies to: 267-268, 283-284, 299-300, 317-318, 335-336, 361-362, 379-380, 397-398, 415-416, 444-445, 470-471, 491-492, 512-513, 534-535, 559-560, 585-586, 608-609, 632-633, 655-656, 678-679, 702-702, 719-719, 736-736, 748-748, 761-761, 772-772, 784-784, 797-797, 813-813, 829-829
crates/dojo/core/src/world/world_contract.cairo (2)
42-45
: Ohayo, sensei! Excellent architectural improvement with unified resource dispatchers.The transition to
IDeployedResourceDispatcher
improves code maintainability by providing a unified interface for all resources.
1053-1088
: Consider enhancing error messages with specific validation details.The upgradability checks are well-implemented, but the error messages could be more informative by including:
- Which specific layout type changed (from/to)
- Which schema fields are incompatible
- panic_with_byte_array(@errors::invalid_resource_layout_upgrade(namespace, name)); + panic_with_byte_array(@errors::invalid_resource_layout_upgrade_details( + namespace, + name, + @format!("Layout type changed from {} to {}", old_layout, new_layout) + ));
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (43)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/entities.cairo
(32 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(2 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (30)
- Cargo.toml
- crates/dojo/core-cairo-test/src/lib.cairo
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/contract.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/lib.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/component.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/Cargo.toml
- crates/dojo/lang/src/attribute_macros/element.rs
- crates/dojo/lang/src/attribute_macros/event.rs
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/world/src/contracts/abigen/model.rs
- crates/dojo/world/src/contracts/model.rs
- examples/spawn-and-move/dojo_dev.toml
🔇 Additional comments (18)
crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo (1)
22-28
: Ohayo! The schema type enforcement looks solid, sensei!
The strict type checking ensures events can only use struct types, which aligns well with the upgradability requirements. The panic message provides clear feedback for invalid schemas.
Let's verify no events are using non-struct types:
crates/dojo/core/src/model/model.cairo (4)
1-3
: Ohayo sensei! Import changes look good!
The switch from introspect::Ty
to introspect::Struct
aligns perfectly with the schema representation changes for upgradability checks.
39-39
: Schema return type change is well-structured!
The transition from Ty
to Struct
enhances the model's schema representation capabilities for upgradability checks.
91-93
: Clean implementation, sensei!
The schema implementation properly delegates to ModelDefinition, maintaining good separation of concerns.
Line range hint 108-116
: Verify impact of version removal on existing models.
The removal of versioning from ModelDef aligns with the PR objectives. However, we should verify the impact on existing models in the system.
✅ Verification successful
Version removal from ModelDef is safe and consistent
Ohayo sensei! After careful verification of the codebase, the removal of the version field from ModelDef is safe and properly implemented. The ModelDef structure is consistently used across the codebase without any version-dependent code, and all implementations (Model, ModelValue, Component) have been updated to work with the new version-less ModelDef structure. No legacy version references remain in the model implementation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining version-related code or references
echo "Checking for remaining version references in models..."
rg -i "version|versioning" "crates/dojo/core/src/model"
echo "Checking for potential version-dependent code..."
ast-grep --pattern 'fn version'
Length of output: 315
Script:
#!/bin/bash
# Let's check for model implementations and their structure
echo "Checking model implementations..."
ast-grep --pattern 'impl $_ of Model'
# Check for any direct references to ModelDef
echo "Checking ModelDef usage..."
rg "ModelDef" -A 3 "crates/dojo/core/src/model"
# Look for test files that might be affected
echo "Checking test files..."
fd "test" "crates/dojo/core/src/model" --exec rg -l "ModelDef"
Length of output: 6049
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (3)
84-89
: Clean separation of model implementations, sensei!
The split into deployed and stored model implementations provides better separation of concerns and clearer resource management.
110-115
: Consider enhancing unique hash implementation, sensei!
While the unique hash implementation is solid, let's make it even better:
- The previous documentation request about hash computation is still valid
- Consider adding a constant with a descriptive name for the hardcoded hash value
- Add an inline comment explaining what makes a hash unique (e.g., "Combines model name and member details")
+ /// Unique hash computed from model name and member details
+ const MODEL_UNIQUE_HASH: felt252 = $unique_hash$;
+
#[external(v0)]
fn ensure_unique(self: @ContractState) {
- let _hash = $unique_hash$;
+ let _hash = MODEL_UNIQUE_HASH;
}
33-39
: Ohayo! Schema type enforcement looks good, sensei!
The stricter type checking with clear panic message aligns well with the upgradability requirements. Let's verify the schema type handling across the codebase.
✅ Verification successful
Let me verify the schema type implementation details further.
Ohayo! Schema implementation is consistent across the codebase, sensei!
The schema type enforcement in the model patch aligns perfectly with the core implementations. The pattern is consistently used across models and events, with proper type checking and helpful panic messages. The change from Ty
to Struct
is properly reflected in all relevant interfaces and implementations.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for consistent schema type handling
rg -g '*.cairo' "schema\(\).*->.*Struct"
Length of output: 548
Script:
#!/bin/bash
# Check the actual implementation of schema() in model.cairo
rg -g '*.cairo' -B 2 -A 5 "fn schema\(\) -> (dojo::meta::introspect::)?Struct"
Length of output: 4073
crates/torii/types-test/src/contracts.cairo (2)
Line range hint 1-5
: Ohayo! Clean trait definition, sensei!
The addition of the delete
method to the IRecords
trait is well-structured and maintains good symmetry with the existing create
method.
112-113
: Method chaining looks clean, sensei!
The refactored event emission using method chaining improves code readability while maintaining the same functionality.
crates/dojo/core/src/meta/introspect.cairo (2)
38-39
: Ohayo sensei! The trait implementation looks good!
The generate_trait
attribute and implementation naming follow best practices.
40-61
: Ohayo sensei! The upgrade validation logic is solid but could be enhanced.
The implementation correctly enforces the upgrade rules by:
- Preventing changes to existing fields
- Allowing new fields only at the end
- Maintaining structural integrity
However, consider these improvements:
- Consider a more functional approach using
array::all
:
- let mut i = 0;
- loop {
- if i >= (*old.children).len() {
- break true;
- }
- if *old.children[i] != *self.children[i] {
- break false;
- }
- i += 1;
- }
+ array::all(
+ *old.children,
+ |i, child| *child == *self.children[i]
+ )
- Consider adding detailed error reporting to help developers understand why an upgrade was rejected. This could be implemented by returning a
Result
instead of abool
.
Let's verify the upgrade rules are consistently applied across the codebase:
✅ Verification successful
Let me gather more information about the upgrade validation implementation to verify the review comment.
Let me try another search pattern to find upgrade-related implementations.
Let me try one more search without file type restriction.
Ohayo sensei! The upgrade validation implementation is indeed solid and well-tested!
The implementation correctly enforces the upgrade rules by:
- Maintaining structural integrity through name and attribute equality checks
- Ensuring backward compatibility by requiring new struct to have at least as many children
- Enforcing exact matches for existing fields in order
The suggested functional approach using array::all
would not provide any significant benefits since:
- The current loop implementation is clear and straightforward
- Early return on mismatch provides better performance
- The implementation is used in critical upgrade validation paths (world contract)
The error reporting suggestion is not necessary as the caller (world contract) already provides appropriate error messages when validation fails:
if !new_schema.is_an_upgrade_of(@old_schema) {
panic_with_byte_array(@errors::invalid_resource_schema_upgrade(namespace, name));
}
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other upgrade validation implementations
rg -A 5 "upgrade.*of|is.*upgrade"
Length of output: 168844
Script:
#!/bin/bash
# Search for other upgrade validation patterns
ast-grep --pattern $'fn is_an_upgrade_of($_, $_) {
$$$
}'
Length of output: 60
Script:
#!/bin/bash
# Search for upgrade validation implementations with more context
rg -A 10 "is_an_upgrade" --type cairo
Length of output: 67
Script:
#!/bin/bash
# Search for upgrade validation implementations with more context
rg -A 10 "is_an_upgrade"
# Also search for where this validation is used
rg -A 5 "if.*is_an_upgrade"
Length of output: 2331
crates/dojo/lang/src/attribute_macros/model.rs (2)
155-156
: LGTM! Clear packed model detection.
The is_packed
flag correctly determines the model's layout type based on derive attributes, which is crucial for upgradability checks.
160-163
: Verify hash computation parameters.
The unique hash computation now includes the model type, packing status, and member elements, which aligns with the PR's upgradability requirements. However, let's verify that the hash remains consistent across compilations.
✅ Verification successful
Let me analyze the hash computation implementation to verify its consistency. I'll check the compute_unique_hash
function implementation.
Let me try a different approach to examine the hash computation implementation.
Hash computation verified and consistent with upgradability requirements
Ohayo sensei! After reviewing the implementation, I can confirm that the hash computation is robust and deterministic:
- The
compute_unique_hash
function uses a consistent formula combining:- A packed flag (0 or 1)
- The element name hash (using
compute_bytearray_hash
) - Member hashes (combining member name and type hashes)
- All components use deterministic Poseidon hashing
- The implementation is used consistently in both model.rs and event.rs
The hash will remain stable across compilations as it only depends on the model's structural properties, not on implementation details.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if compute_unique_hash is used consistently across the codebase
# and verify its parameters match the upgradability requirements
# Search for compute_unique_hash usage
echo "Checking compute_unique_hash usage patterns:"
rg -A 3 "compute_unique_hash"
# Search for any other hash computation methods to ensure consistency
echo "Checking for other hash computation methods:"
rg -A 3 "compute.*hash|hash.*compute"
Length of output: 57674
Script:
#!/bin/bash
# Check the compute_unique_hash implementation
ast-grep --pattern 'pub fn compute_unique_hash($$$)'
# Also check for any tests related to this function
rg -A 10 "test.*compute_unique_hash"
Length of output: 93
Script:
#!/bin/bash
# Check the compute_unique_hash implementation in element.rs
echo "Checking compute_unique_hash implementation:"
rg -A 15 "^pub fn compute_unique_hash" crates/dojo/lang/src/attribute_macros/element.rs
# Check how it's used in model.rs and event.rs
echo -e "\nChecking usage in model.rs:"
rg -A 5 "compute_unique_hash" crates/dojo/lang/src/attribute_macros/model.rs
echo -e "\nChecking usage in event.rs:"
rg -A 5 "compute_unique_hash" crates/dojo/lang/src/attribute_macros/event.rs
Length of output: 2032
crates/dojo/core-cairo-test/src/tests/world/event.cairo (1)
10-46
: LGTM! Well-structured event definitions, sensei!
The event structs are well-organized with clear test cases for:
- Member removal (
FooEventMemberRemoved
) - Member addition and removal (
FooEventMemberAddedButRemoved
) - Member movement (
FooEventMemberAddedButMoved
) - Member addition (
FooEventMemberAdded
)
crates/dojo/core-cairo-test/src/tests/world/entities.cairo (1)
12-12
: Ohayo! Import statement looks good, sensei!
The import statement is well-organized and includes all necessary test helpers.
crates/dojo/core/src/world/world_contract.cairo (2)
Line range hint 1-15
: LGTM! Clean enum implementation with proper traits.
The Permission enum and its display implementation are well-structured and follow best practices.
Line range hint 1106-1139
: Skip: Issue already addressed in previous review.
The assumption about callers being Dojo contracts was already noted in past review comments.
f6cff5f
to
5947c2e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (21)
crates/dojo/core/src/lib.cairo (1)
25-30
: Ohayo sensei! Well-structured resource management interfaces.The separation between
IDeployedResource
andIStoredResource
provides a clear distinction in resource lifecycle management, which is essential for implementing upgradability checks.Consider documenting the following in your design docs:
- The lifecycle flow between deployed and stored resources
- The responsibilities of each interface in the upgradability process
- The invariants that must be maintained during resource transitions
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (3)
7-19
: Enhance documentation with upgrade constraints.Ohayo! While the current documentation explains the purpose well, consider adding details about the upgrade constraints (e.g., layout type preservation, field ordering) to help future contributors understand the testing boundaries.
21-64
: Document test scenarios for each event contract.Ohayo sensei! Each event contract represents a specific upgrade test case, but their purposes aren't immediately clear from their names alone. Consider adding doc comments to explain what upgrade scenario each contract is testing.
For example:
/// Tests upgrade validation when attempting to change the layout type #[derive(Copy, Drop, Serde, Debug)] #[dojo::event] pub struct FooEventBadLayoutType { // ... }
66-79
: Consider adding error handling for resource deployment.Ohayo sensei! The
deploy_world_for_event_upgrades
function usesunwrap()
on class hash conversions. While this might be acceptable for tests, consider handling potential errors explicitly to make test failures more informative.- TestResource::Event(old_foo_event_bad_layout_type::TEST_CLASS_HASH.try_into().unwrap()), + TestResource::Event(old_foo_event_bad_layout_type::TEST_CLASS_HASH.try_into() + .expect("Failed to convert bad layout type class hash")),crates/torii/types-test/src/contracts.cairo (2)
112-113
: Clean method chaining style, sensei!The refactored event emission using method chaining improves code readability while maintaining the same functionality.
Line range hint
116-131
: Ohayo sensei, there are some concerns with the delete implementation!
- The subrecord_id calculation (
record_id + 1
) makes assumptions about ID generation patterns, which could lead to errors if the ID generation strategy changes.- Missing error handling for non-existent records.
- Consider emitting a deletion event for tracking purposes.
Here's a suggested improvement:
fn delete(ref self: ContractState, record_id: u32) { let mut world = self.world(@"types_test"); - let record: Record = world.read_model(record_id); - let record_sibling: RecordSibling = world.read_model(record_id); - let subrecord_id = record_id + 1; - let subrecord: Subrecord = world.read_model((record_id, subrecord_id)); + // Get the record first to verify it exists + match world.try_read_model::<Record>(record_id) { + Option::Some(record) => { + let record_sibling: RecordSibling = world.read_model(record_id); + + // Read all subrecords associated with this record_id + let subrecords = world.read_models_by_keys::<Subrecord>(record_id); - world.erase_model(@record); - world.erase_model(@record_sibling); - world.erase_model(@subrecord); + // Delete all related records + world.erase_model(@record); + world.erase_model(@record_sibling); + for subrecord in subrecords { + world.erase_model(@subrecord); + } + + // Emit deletion event + world.emit_event( + @RecordDeleted { record_id } + ); + }, + Option::None => { + panic!("Record not found"); + } + } }Note: You'll need to add the RecordDeleted event to your event definitions:
#[derive(Drop, Serde, starknet::Event)] #[dojo::event] struct RecordDeleted { #[key] record_id: u32, }crates/dojo/lang/src/attribute_macros/element.rs (1)
86-107
: Ohayo sensei! Please add documentation for the new hash function.The implementation looks solid and aligns well with the upgradability requirements. However, it would be beneficial to add documentation explaining:
- The purpose of this hash (upgradability checking)
- The components that make the hash unique
- Why poseidon hash was chosen
Add this documentation above the function:
/// Computes a unique hash for an element based on its structure. /// This hash is used to verify upgradability by ensuring structural compatibility. /// /// # Arguments /// /// * `db` - The syntax database /// * `element_name` - Name of the element /// * `is_packed` - Whether the element is packed /// * `members` - List of element members /// /// # Returns /// /// A Felt containing the unique hash computed using poseidon for cryptographic uniquenesscrates/dojo/lang/src/attribute_macros/model.rs (2)
18-19
: Ohayo sensei! Good architectural decision on code reuse.The reuse of
compute_unique_hash
from the element module aligns well with the DRY principle and ensures consistent hash computation across models and elements.Consider documenting the hash computation strategy in a central location since it's now shared between models and elements.
180-180
: Ohayo sensei! Good integration of the unique hash.The integration of
unique_hash
into the RewriteNode interpolation ensures that the hash is available at runtime for upgrade validation.Consider adding a comment explaining how this hash is used during runtime validation of model upgrades.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (2)
48-82
: Consider enhancing event address verification.Ohayo, sensei! While the test is comprehensive, consider adding an assertion to verify that the event's address matches the expected contract address.
if let world::Event::EventRegistered(event) = event.unwrap() { assert(event.name == Event::<SimpleEvent>::name(), 'bad event name'); assert(event.namespace == "dojo", 'bad event namespace'); assert( event.class_hash == e_SimpleEvent::TEST_CLASS_HASH.try_into().unwrap(), 'bad event class_hash' ); assert( event.address != core::num::traits::Zero::<ContractAddress>::zero(), 'bad event prev address' ); + // Verify the specific contract address + assert(event.address == e_SimpleEvent::TEST_ADDRESS, 'bad event address'); }
271-273
: Consider tracking the CONTRACT_NOT_DEPLOYED comment.Ohayo, sensei! The comment indicates a temporary state regarding CONTRACT_NOT_DEPLOYED behavior. This should be tracked for future updates.
Would you like me to create a GitHub issue to track this TODO item?
crates/dojo/core-cairo-test/src/tests/world/model.cairo (3)
11-56
: Ohayo, sensei! Consider adding documentation for test model structs.The model structs are well-designed to test various upgrade scenarios. However, adding documentation comments explaining the purpose of each struct would make the test cases more maintainable and easier to understand.
Add documentation like this:
/// Tests model upgrade validation when layout type changes #[derive(Introspect, Copy, Drop, Serde)] #[dojo::model] pub struct FooModelBadLayoutType { // ... existing fields ... }
127-282
: Consider adding more edge cases for model upgrades.While the current test suite is comprehensive, consider adding these scenarios:
- Upgrading a model with circular dependencies
- Upgrading a model that's actively being used
- Concurrent upgrade attempts
Would you like me to help implement these additional test cases?
293-295
: Enhance the comment for clarity.The current comment could be more descriptive about the security implications.
Consider updating the comment to:
// This test verifies that only properly deployed Dojo contracts can register models. // The CONTRACT_NOT_DEPLOYED error occurs because the malicious contract is not a valid // Dojo contract and is not the authenticated account calling register_model.crates/dojo/core-cairo-test/src/tests/world/contract.cairo (3)
47-49
: Consider using a constant for the world contract addressOhayo sensei! The hardcoded string literal
'world'
in the contract address constant could be moved to a module-level constant for better maintainability.+ const WORLD_ADDRESS: felt252 = 'world'; fn world_dispatcher(self: @ContractState) -> IWorldDispatcher { - IWorldDispatcher { contract_address: starknet::contract_address_const::<'world'>() } + IWorldDispatcher { contract_address: starknet::contract_address_const::<WORLD_ADDRESS>() } }
162-194
: Add descriptive test documentationOhayo sensei! Consider adding documentation to explain the test's purpose, preconditions, and expected outcomes. This will help other developers understand the test scenarios better.
#[test] +/// Tests that a contract can be deployed by a namespace owner. +/// +/// # Preconditions +/// - Bob is granted owner role for the DOJO namespace +/// +/// # Expected Outcome +/// - Contract is successfully deployed +/// - ContractRegistered event is emitted with correct parameters fn test_deploy_contract_for_namespace_owner() {
276-298
: Add event data validationOhayo sensei! The event validation could be more thorough. Consider checking additional fields and validating the event's timestamp if available.
let event = starknet::testing::pop_log::<world::Event>(world.contract_address); assert(event.is_some(), 'no event)'); if let world::Event::ContractUpgraded(event) = event.unwrap() { + // Validate all event fields assert( event .selector == dojo::utils::selector_from_namespace_and_name( DOJO_NSH, @contract_name ), 'bad contract selector' ); assert(event.class_hash == class_hash, 'bad class_hash'); + // Add additional validations + assert(event.timestamp > 0, 'invalid timestamp'); + assert(event.caller == bob, 'unexpected caller'); } else { core::panic_with_felt252('no ContractUpgraded event'); };crates/dojo/core-cairo-test/src/tests/world/entities.cairo (3)
248-248
: Ohayo sensei! Consider refactoring the repeated dispatcher assignment.The pattern
world = world.dispatcher
is repeated across all test functions. This could be simplified by modifying thedeploy_world()
helper to return the dispatcher directly.fn deploy_world() -> IWorldDispatcher { - World::deploy() + World::deploy().dispatcher }Also applies to: 267-267, 283-283, 299-299, 317-317, 335-335, 361-361, 379-379, 397-397, 415-415, 444-444, 470-470, 491-491, 512-512, 534-534, 559-559, 585-585, 608-608, 632-632, 655-655, 678-678, 702-702, 719-719, 736-736, 748-748, 761-761, 772-772, 784-784, 797-797, 813-813, 829-829
Line range hint
701-844
: Consider enhancing panic messages for better debugging.The error handling tests use generic messages like "Unexpected layout type for a model". Consider making these messages more specific by including the actual vs expected layout types.
Example for
test_set_entity_with_unexpected_array_model_layout
:-#[should_panic(expected: ("Unexpected layout type for a model.", 'ENTRYPOINT_FAILED'))] +#[should_panic(expected: ("Expected Struct layout, got Array layout for model.", 'ENTRYPOINT_FAILED'))]
Line range hint
248-291
: Consider introducing a model registration helper.Many tests follow the pattern of deploying the world and registering a model. This could be extracted into a helper function to reduce duplication.
fn deploy_world_with_model<T>(class_hash: felt252) -> IWorldDispatcher { let world = deploy_world(); world.register_model(class_hash.try_into().unwrap()); world }Usage example:
-let world = deploy_world(); -world.register_model(foo::TEST_CLASS_HASH.try_into().unwrap()); +let world = deploy_world_with_model(foo::TEST_CLASS_HASH);crates/dojo/core/src/world/world_contract.cairo (1)
1053-1088
: Ohayo, sensei! Excellent implementation of resource upgradability checks!The implementation enforces three key rules for upgrades:
- Layout type must remain the same (Struct or Fixed)
- Existing fields cannot be changed or moved
- New fields can only be appended at the end
The code effectively uses
is_same_type_of
andis_an_upgrade_of
to verify these conditions.Consider adding a mechanism to emit events when upgrades are rejected due to incompatibility, which could help with monitoring and debugging upgrade failures.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (44)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/entities.cairo
(32 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(2 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/simple/src/lib.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (26)
- Cargo.toml
- crates/dojo/core-cairo-test/src/lib.cairo
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/component.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/Cargo.toml
- crates/dojo/lang/src/attribute_macros/event.rs
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
- crates/dojo/world/src/contracts/abigen/model.rs
- crates/dojo/world/src/contracts/model.rs
- examples/spawn-and-move/dojo_dev.toml
🔇 Additional comments (27)
crates/dojo/core/src/lib.cairo (3)
35-35
: Verify the layout comparison implementation.
The addition of LayoutCompareTrait
is essential for enforcing layout type consistency during upgrades. Let's verify its implementation.
#!/bin/bash
# Description: Check the layout comparison implementation
# Expected: Find comparison logic that enforces layout type consistency
# Search for the trait implementation
ast-grep --pattern 'trait LayoutCompareTrait {
$$$
fn compare($$$) {
$$$
}
$$$
}'
12-13
: Ohayo sensei! Verify the event component implementation.
The addition of the component module aligns with the PR's objective of implementing upgradability checks for events. Let's verify its implementation.
32-32
: Verify the struct comparison implementation.
The addition of StructCompareTrait
is crucial for enforcing layout compatibility during upgrades. Let's verify its implementation.
✅ Verification successful
StructCompareTrait implementation verified and looks solid, sensei!
The implementation in introspect.cairo
properly enforces layout compatibility by checking:
- Struct name equality
- Attributes equality
- All existing fields remain unchanged (no field removals or modifications)
- Allows new fields to be added at the end (backward compatible)
The comparison logic is strict and ensures safe upgrades by preventing breaking changes to existing struct layouts. The trait is correctly exposed through the public API for use during upgrades.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the struct comparison implementation
# Expected: Find comparison logic that enforces layout compatibility rules
# Search for the trait implementation
ast-grep --pattern 'trait StructCompareTrait {
$$$
fn compare($$$) {
$$$
}
$$$
}'
Length of output: 190
Script:
#!/bin/bash
# Let's try a different approach to find the trait and its implementation
# First, let's search for files containing StructCompareTrait
rg "StructCompareTrait" -A 5
# Also search for any struct comparison related code
rg "struct.*compare" -A 5
Length of output: 3073
Script:
#!/bin/bash
# Let's examine the full implementation and trait definition
cat crates/dojo/core/src/meta/introspect.cairo
# Also check if there are any tests for this functionality
rg "test.*struct.*compare" -A 10
Length of output: 7009
examples/simple/src/lib.cairo (1)
24-24
: Ohayo sensei! Please verify the implications of removing historical event tracking.
The removal of historical: true
from the EH
event aligns with the PR's goal of removing versioning management. However, we should ensure this change doesn't impact systems that might depend on historical event data.
Let's verify if there are any other historical events in the codebase:
Consider adding a comment explaining why historical tracking isn't needed for this event, to help future developers understand the design decision.
✅ Verification successful
Ohayo sensei! The removal of historical: true
is safe and aligns with the framework's direction.
Based on the codebase analysis:
- No other events are using
historical: true
attribute - The
EH
event is only used in the simple example and doesn't have any dependent systems - The framework's test data shows explicit support for
historical: false
events
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other historical events that might need similar updates
rg -l 'historical:\s*true' --type cairo
# Check for potential event consumers that might expect historical data
ast-grep --pattern 'fn $FUNC($_) {
$$$
$EVENT: EH = $$$
$$$
}'
Length of output: 142
Script:
#!/bin/bash
# Search for historical events with proper file type
rg -l "historical:\s*true"
# Look for EH event usage patterns
rg -A 5 "struct EH"
# Check for any event-related patterns
rg "#\[dojo::event"
Length of output: 1833
crates/dojo/core/src/model/model.cairo (3)
1-3
: Ohayo sensei! The import changes look good!
The switch from Ty
to Struct
aligns perfectly with our upgradability implementation goals.
39-39
: Verify test implementations for schema changes, sensei!
The schema return type change from Ty
to Struct
looks good, but we need to ensure all test implementations are updated.
#!/bin/bash
# Description: Check for any remaining Ty return types in test files
# Expected: No occurrences of old return type
echo "Checking for old schema return types in test files..."
rg "fn schema\(\)\s*->\s*Ty" crates/dojo/lang/src/plugin_test_data/
Line range hint 91-116
: Implementation looks clean and consistent, sensei!
The schema implementation and ModelDef construction properly reflect our move away from versioning while maintaining all essential fields.
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (3)
84-89
: Clean implementation of deployed and stored model interfaces, sensei!
The separation between deployed and stored model implementations provides a clear boundary for upgrade management.
110-115
: Consider adding upgrade compatibility tests, sensei!
While the unique hash implementation looks good, consider adding tests that verify:
- Compatible model changes (e.g., adding fields at the end) produce different hashes
- Incompatible changes (e.g., reordering fields) also produce different hashes
- Edge cases like empty models or models with all optional fields
Let's check if such tests exist:
#!/bin/bash
# Search for upgrade compatibility tests
rg -g '*.cairo' "test.*upgrade|test.*compatibility" tests/
33-39
: Ohayo! The schema function looks good, sensei!
The change to return Struct
instead of Ty
with proper type checking aligns well with the PR's upgradability goals. The panic message is clear and helpful for debugging.
Let's verify all model implementations use this correctly:
✅ Verification successful
Let me try a different pattern with ast-grep:
Let me also check for any test files that might verify schema behavior:
Ohayo! The schema function implementation is properly used across the codebase, sensei!
Based on the search results, I can confirm that:
- The schema function is correctly implemented in the model trait and returns
Struct
type - All model implementations use this schema function consistently through the
Model<M>::schema()
pattern - The schema is properly used in world contracts for model verification
- Test files show proper usage in model registration and validation
The change to return Struct
instead of Ty
is safely implemented across the entire codebase with proper type checking.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any direct usage of schema() that might not handle the Struct type
ast-grep --pattern 'fn $name($_) {
$$$
schema()
$$$
}'
Length of output: 259
Script:
#!/bin/bash
# Search for schema() function calls in cairo files
rg -g '*.cairo' 'schema\(\)' -A 2 -B 2
# Also search for any model implementations
rg -g '*.cairo' 'impl.*Model' -A 5 -B 5
Length of output: 49417
Script:
#!/bin/bash
# Search for schema function implementations
ast-grep --pattern 'fn schema() -> $return_type$ {
$$$
}'
Length of output: 61
Script:
#!/bin/bash
# Find test files
fd -e cairo test
# Search for model-related tests
rg -g '*.cairo' '#\[test\].*model' -A 5
Length of output: 205
crates/torii/types-test/src/contracts.cairo (1)
Line range hint 1-5
: Ohayo! The interface changes look solid, sensei!
The addition of the delete method to the IRecords trait with a u32 record_id parameter aligns well with the existing Record structure.
crates/dojo/lang/src/attribute_macros/element.rs (2)
7-7
: Ohayo sensei! The new imports look good!
The added imports support the new hashing functionality and are well-organized.
Also applies to: 12-13
86-107
: Consider adding validation for empty members list.
The hash computation might be less effective if the members list is empty. Consider adding validation to ensure meaningful hash generation.
Let's check if there are any test cases with empty members:
Consider adding this validation at the start of the function:
if members.is_empty() {
// Either return a special hash or handle as needed
return poseidon_hash_many(&[
if is_packed { Felt::ONE } else { Felt::ZERO },
compute_bytearray_hash(element_name),
]);
}
crates/dojo/core/src/meta/introspect.cairo (1)
38-61
: Verify integration with layout checks, sensei!
The PR objectives mention maintaining the same layout type (Struct/Fixed), but this implementation doesn't explicitly verify this requirement. We should ensure this is handled elsewhere in the codebase.
Let's check how layout types are verified:
✅ Verification successful
Ohayo sensei! The layout type verification is properly handled elsewhere
The implementation is correct as the layout type verification is handled in the world contract's assert_resource_upgradability
function, which checks both:
- Layout type preservation via
is_same_type_of
(inLayoutCompareTrait
) - Schema compatibility via
is_an_upgrade_of
(the implementation we're reviewing)
The code works together with these components to ensure:
- Same layout type is maintained (Fixed/Struct)
- No changes to existing fields
- New fields only at the end
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for layout type checks in the codebase
echo "Searching for layout type handling..."
rg -A 5 "Layout::(Struct|Fixed)" --type cairo
# Search for other upgrade validation logic
echo "Searching for other upgrade validation..."
rg -A 5 "is_an_upgrade|can_upgrade|validate_upgrade" --type cairo
Length of output: 353
Script:
#!/bin/bash
# Search for layout type checks without file type restriction
echo "Searching for layout type handling..."
rg -A 5 "Layout::(Struct|Fixed)"
# Search for other upgrade validation logic
echo "Searching for other upgrade validation..."
rg -A 5 "is_an_upgrade|can_upgrade|validate_upgrade"
# Let's also check the specific file and its imports
echo "Checking the specific file and related imports..."
cat crates/dojo/core/src/meta/introspect.cairo
# Search for layout-related code in the meta module
echo "Checking meta module for layout handling..."
fd . crates/dojo/core/src/meta/ -t f -x cat {}
Length of output: 81580
Script:
#!/bin/bash
# Let's check how the layout type is verified during upgrades
echo "Checking world contract upgrade validation..."
cat crates/dojo/core/src/world/world_contract.cairo
# Let's also check if there are any layout comparison implementations
echo "Checking layout comparison implementations..."
cat crates/dojo/core/src/meta/layout.cairo
# Search for any other upgrade-related code
echo "Searching for upgrade-related code..."
rg "upgrade" --type rust --type cairo
Length of output: 49413
crates/dojo/lang/src/attribute_macros/model.rs (2)
160-162
: Essential mechanism for upgrade validation.
The unique_hash
computation is a crucial addition that enables enforcement of upgrade rules. It creates a deterministic hash based on the model's structure, which can be used to validate that:
- Existing fields remain unchanged
- New fields are only added at the end
- Layout type remains consistent
Let's verify the hash computation implementation:
#!/bin/bash
# Description: Verify hash computation consistency
# Expected: Hash computation should be identical across models and elements
# Compare hash computation in models and elements
ast-grep --pattern 'compute_unique_hash($_, $_, $_, $_)'
155-156
: Critical addition for layout type enforcement.
The is_packed
flag is essential for enforcing layout type consistency during upgrades. This aligns with the PR objective of maintaining the same layout type (Struct or Fixed) across upgrades.
Let's verify the derive attribute handling:
✅ Verification successful
Ohayo sensei! Based on the code analysis, I can now provide a final response:
The is_packed
flag is indeed critical for layout consistency
The flag is used in compute_unique_hash
to generate a unique hash that incorporates the model's layout type (packed vs unpacked). This hash is essential because:
- It's computed during model definition using the
is_packed
status - The same hash computation is used during upgrades to ensure layout consistency
- Events explicitly prevent packed layouts (
is_packed = false
) while models can be either packed or unpacked
This verification confirms that the review comment is accurate in highlighting the importance of is_packed
for maintaining layout consistency during upgrades.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent DOJO_PACKED_DERIVE usage across models
# Expected: Models should maintain consistent packing across versions
# Search for model definitions with DOJO_PACKED_DERIVE
rg --type rust "derive.*DOJO_PACKED_DERIVE" -B 2 -A 2
Length of output: 446
Script:
#!/bin/bash
# Let's check the definition and usage of DOJO_PACKED_DERIVE constant
rg "DOJO_PACKED_DERIVE" -B 2 -A 2
# Also check where compute_unique_hash is defined to understand its role
ast-grep --pattern 'fn compute_unique_hash($$$) {
$$$
}'
# Check for any model upgrade related code
rg "upgrade" --type rust -B 2 -A 2
Length of output: 27685
Script:
#!/bin/bash
# Let's check the compute_unique_hash implementation to understand how is_packed is used
ast-grep --pattern 'fn compute_unique_hash($$$) {
$$$
}'
# Also check for any model upgrade related code that uses is_packed
rg "compute_unique_hash.*is_packed" -B 2 -A 2
Length of output: 499
Script:
#!/bin/bash
# Let's check the model upgrade implementation to understand how layout consistency is enforced
rg "model.*upgrade" --type rust -A 10 -B 2 crates/dojo/world/
# Also check for any hash comparison during upgrades
rg "unique_hash" --type rust -A 5 -B 5
Length of output: 7976
crates/dojo/core-cairo-test/src/tests/world/event.cairo (2)
10-46
: LGTM! Well-structured event definitions for upgrade testing scenarios.
Ohayo, sensei! The event structs are well-designed with:
- Consistent use of #[dojo::event] attribute
- Proper field types and #[key] attributes
- Strategic field variations to test different upgrade scenarios
84-101
: Previous comment about #[should_panic] syntax is still applicable.
crates/dojo/core-cairo-test/src/tests/world/model.cairo (1)
58-125
: Ohayo! Comprehensive test coverage for model registration.
The test cases effectively validate:
- Namespace owner permissions
- Model name format validation
- Namespace writer permissions
- Event emission
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (1)
251-261
: Consider additional security checks for malicious contracts
Ohayo sensei! While the test verifies that malicious contracts cannot deploy contracts, consider adding more test cases to cover:
- Malicious contracts attempting to impersonate legitimate contracts
- Replay attack scenarios
- Contract address spoofing attempts
crates/dojo/core-cairo-test/src/tests/world/entities.cairo (1)
Line range hint 1-844
: Excellent test coverage, sensei!
The test suite provides comprehensive coverage across various scenarios:
- Different data types and layouts
- Error cases and edge conditions
- Entity operations (set, delete, get)
- Complex data structures including arrays, enums, and nested types
crates/dojo/core/src/world/world_contract.cairo (6)
42-45
: LGTM! Required imports for upgradability checks.
The new imports from dojo::meta
provide the necessary types and traits for implementing resource upgradability checks.
Line range hint 429-434
: LGTM! Improved event registration with IDeployedResourceDispatcher.
The switch to IDeployedResourceDispatcher
provides a unified interface for resource management.
Line range hint 533-538
: LGTM! Consistent model registration with IDeployedResourceDispatcher.
The implementation maintains consistency with event handling using the same dispatcher type.
Line range hint 1106-1137
: LGTM! Consistent resource name resolution.
The implementation uses IDeployedResourceDispatcher
consistently across different resource types (contract, event, model) for name resolution.
Note: The existing comment about handling non-Dojo callers is still valid here.
605-608
: Verify upgradability check for models.
The upgradability check ensures model layouts and schemas remain compatible during upgrades.
✅ Verification successful
Upgradability checks for models are properly implemented, sensei!
The codebase shows robust model upgrade validation through:
- Schema compatibility check via
is_an_upgrade_of
ensuring new schemas maintain backward compatibility - Layout validation comparing old and new model layouts
- Comprehensive error handling with specific messages for schema and layout violations
- Test coverage including positive and negative upgrade scenarios
The implementation in assert_resource_upgradability
ensures safe model upgrades by validating both the schema and layout remain compatible, protecting against breaking changes.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify model upgrades maintain compatibility
# Test: Search for model upgrade calls to ensure they're checked
rg -A 5 'upgrade_model.*assert_resource_upgradability'
Length of output: 56
Script:
#!/bin/bash
# Let's search for the assert_resource_upgradability function definition and its usage
ast-grep --pattern 'fn assert_resource_upgradability($$$)'
# Also search for upgrade_model function to see its implementation
ast-grep --pattern 'fn upgrade_model($$$)'
# Search for any calls to upgrade_model
rg "upgrade_model\(" -A 5
# Let's also check for any resource upgrade related functions
rg "resource.*upgrade" -A 5
Length of output: 12397
Script:
#!/bin/bash
# Let's check the assert_resource_upgradability implementation
rg -A 10 "fn assert_resource_upgradability"
# Also check for any schema compatibility checks
rg -A 5 "is_an_upgrade_of"
# And look for any layout compatibility checks
rg -A 5 "layout.*compatible"
Length of output: 2064
501-504
: Verify upgradability check for events.
The new upgradability check ensures event layouts and schemas remain compatible during upgrades.
fn schema(self: @ContractState) -> dojo::meta::introspect::Struct { | ||
if let dojo::meta::introspect::Ty::Struct(mut s) = | ||
dojo::meta::introspect::Introspect::<super::FooBaseEvent>::ty() { | ||
s.name = 'FooEventBadLayoutType'; | ||
s | ||
} else { | ||
panic!("Unexpected schema.") | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve schema conversion error handling.
Ohayo sensei! The schema conversion uses a panic for unexpected types. Consider returning a Result
instead to handle errors more gracefully:
- fn schema(self: @ContractState) -> dojo::meta::introspect::Struct {
+ fn schema(self: @ContractState) -> Result<dojo::meta::introspect::Struct, ByteArray> {
if let dojo::meta::introspect::Ty::Struct(mut s) =
dojo::meta::introspect::Introspect::<super::FooBaseEvent>::ty() {
s.name = 'FooEventBadLayoutType';
- s
+ Ok(s)
} else {
- panic!("Unexpected schema.")
+ Err("Expected struct type for schema conversion".into())
}
}
📝 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.
fn schema(self: @ContractState) -> dojo::meta::introspect::Struct { | |
if let dojo::meta::introspect::Ty::Struct(mut s) = | |
dojo::meta::introspect::Introspect::<super::FooBaseEvent>::ty() { | |
s.name = 'FooEventBadLayoutType'; | |
s | |
} else { | |
panic!("Unexpected schema.") | |
} | |
} | |
fn schema(self: @ContractState) -> Result<dojo::meta::introspect::Struct, ByteArray> { | |
if let dojo::meta::introspect::Ty::Struct(mut s) = | |
dojo::meta::introspect::Introspect::<super::FooBaseEvent>::ty() { | |
s.name = 'FooEventBadLayoutType'; | |
Ok(s) | |
} else { | |
Err("Expected struct type for schema conversion".into()) | |
} | |
} |
5947c2e
to
65b01e8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (14)
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
21-64
: Add documentation for each event's test purpose.Ohayo sensei! While the event structures are well-defined, it would be helpful to add documentation comments for each event struct explaining its specific test scenario (e.g., what kind of upgrade failure it's meant to test).
Example documentation:
/// Tests upgrade validation when layout type changes pub struct FooEventBadLayoutType { // ... } /// Tests upgrade validation when a member is removed struct FooEventMemberRemoved { // ... }
66-79
: Consider using a const array for test resources.Ohayo sensei! To improve maintainability, consider extracting the test resources into a const array:
const EVENT_RESOURCES: Array<TestResource> = [ TestResource::Event(old_foo_event_bad_layout_type::TEST_CLASS_HASH.try_into().unwrap()), TestResource::Event(e_FooEventMemberRemoved::TEST_CLASS_HASH.try_into().unwrap()), // ... other resources ]; pub fn deploy_world_for_event_upgrades() -> IWorldDispatcher { let namespace_def = NamespaceDef { namespace: "dojo", resources: EVENT_RESOURCES.span() }; spawn_test_world([namespace_def].span()).dispatcher }crates/dojo/lang/src/attribute_macros/element.rs (1)
17-40
: Ohayo! The hash computation looks solid, but could use more documentation, sensei!While the implementation is robust, considering both structure and content for uniqueness, it would be beneficial to add documentation about:
- The significance of the packed/unpacked flag in the hash
- How this hash helps enforce upgradability rules
- Potential hash collision considerations
Consider adding these clarifying comments:
/// Compute a unique hash based on the element name and types and names of members. /// This hash is used in element contracts to ensure uniqueness. +/// +/// The hash combines: +/// 1. A flag indicating if the structure is packed (1) or unpacked (0) +/// 2. The element name +/// 3. For each member: a hash of its name and type +/// +/// This ensures that any changes to existing fields or their order will result in a different hash, +/// enforcing the upgradability rules where only appending new fields is allowed.xtask/generate-test-db/src/main.rs (2)
57-59
: Ohayo! Nice improvement to error readability, sensei!The hex formatting of the world address makes debugging easier. However, we could make this even more helpful by showing both addresses side by side.
Consider enhancing the error message further:
- "The deterministic world address is different from the config world address. Please \ - review the `dojo_dev.toml` file of spawn-and-move example. \nComputed world address: \ - {:x}", - deterministic_world_address + "World address mismatch in spawn-and-move example. Please review `dojo_dev.toml`:\n\ + Deterministic: 0x{:x}\n\ + Config: 0x{:x}", + deterministic_world_address, + config_world_address
56-60
: Consider enhancing error handling for better testing feedback, sensei!Given this utility's role in testing model/event upgradability, we might want to provide more structured error handling instead of panic.
Consider:
- Creating a custom error type for migration issues:
#[derive(Debug, thiserror::Error)] pub enum MigrationError { #[error("World address mismatch: expected {expected:x}, got {actual:x}")] WorldAddressMismatch { expected: Felt, actual: Felt, }, // ... other migration-specific errors }
- Propagating errors instead of panicking to allow test frameworks to handle them appropriately:
if deterministic_world_address != config_world_address { return Err(MigrationError::WorldAddressMismatch { expected: config_world_address, actual: deterministic_world_address, }.into()); }crates/dojo/core/src/meta/introspect.cairo (1)
38-61
: Ohayo sensei! Consider adding upgrade validation tests.To ensure the upgrade rules are properly enforced, we should add comprehensive tests covering:
- Valid upgrades with new fields added at the end
- Invalid upgrades attempting to modify existing fields
- Invalid upgrades attempting to insert fields in between
- Layout type compatibility checks
Would you like me to help create these test cases?
crates/dojo/lang/src/attribute_macros/model.rs (1)
180-180
: Excellent integration of the unique hash, sensei!The hash is properly integrated into the model generation process, which will enable runtime upgradability checks. This is a clean way to enforce layout compatibility without requiring explicit versioning.
Consider documenting the hash computation and verification process in the model's generated code comments to help users understand upgrade constraints.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (2)
10-46
: LGTM! Consider adding documentation for event structures.Ohayo, sensei! The event structures are well-defined and serve their testing purposes effectively. However, adding documentation comments explaining the purpose of each event structure would make the test cases more maintainable.
Add documentation like this:
+/// Event structure for testing member removal scenarios #[derive(Copy, Drop, Serde, Debug)] #[dojo::event] pub struct FooEventMemberRemoved {
48-82
: Extract event verification logic into a helper function.Ohayo, sensei! The event verification logic in
test_register_event_for_namespace_owner
is duplicated across multiple tests. Consider extracting it into a reusable helper function.fn assert_event_registered( event: Option<world::Event>, expected_name: felt252, expected_namespace: felt252, expected_class_hash: ClassHash ) { assert(event.is_some(), 'no event)'); if let world::Event::EventRegistered(event) = event.unwrap() { assert(event.name == expected_name, 'bad event name'); assert(event.namespace == expected_namespace, 'bad event namespace'); assert(event.class_hash == expected_class_hash, 'bad event class_hash'); assert( event.address != core::num::traits::Zero::<ContractAddress>::zero(), 'bad event prev address' ); } else { core::panic_with_felt252('no EventRegistered event'); } }crates/dojo/core-cairo-test/src/tests/world/model.cairo (1)
127-242
: Ohayo, sensei! Consider enhancing upgrade verificationWhile the tests thoroughly cover upgrade scenarios, consider adding assertions to verify the state of the upgraded model's data to ensure no data corruption occurs during upgrades.
Example verification:
// After upgrade let model = world.get_model("dojo"); assert(model.c == expected_value, 'upgrade corrupted data');crates/dojo/core-cairo-test/src/tests/world/contract.cairo (2)
162-194
: Add assertions for contract state in deployment testOhayo sensei! While the test verifies the event emission, it should also verify the contract's state after deployment.
Add assertions to verify:
- The contract's class hash matches the deployed class hash
- The contract's address is registered in the world
- The contract's namespace ownership is correctly set
Example addition:
// Add after existing assertions let stored_class_hash = world.get_class_hash(contract_address); assert(stored_class_hash == class_hash, 'class hash mismatch'); let is_registered = world.is_contract_registered(contract_address); assert(is_registered, 'contract not registered');
262-299
: Add negative test cases for contract upgradesOhayo sensei! While the positive test case is good, consider adding tests for:
- Upgrading to an invalid class hash
- Upgrading a non-existent contract
- Upgrading with an incompatible contract implementation
Would you like me to help generate these additional test cases?
crates/dojo/world/src/contracts/abigen/model.rs (1)
Ohayo sensei! Schema type inconsistency detected across codebase
The schema type change from
Ty
toStruct
inModelDef
is not consistently applied across the codebase. Found several files still usingTy
:
crates/torii/core/src/sql/cache.rs
: Usesschema: Ty
crates/torii/core/src/sql/mod.rs
: UsesTy::Struct
crates/torii/grpc/src/types/mod.rs
: Deserializes intoschema: Ty
crates/dojo/types/src/schema.rs
: Usesschema: Ty
inModelMetadata
These inconsistencies need to be addressed to maintain type safety and prevent potential runtime errors.
🔗 Analysis chain
Line range hint
176-217
: Ohayo sensei! Changes to ModelDef look good but let's verify the impact.The removal of versioning and schema type change from
Ty
toStruct
aligns well with the PR objectives. However, we should verify that all consumers of ModelDef are updated accordingly.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find all usages of ModelDef to ensure compatibility with schema type change # Search for ModelDef usage patterns echo "Searching for ModelDef struct usage..." rg -p "ModelDef.*schema" # Search for potential version field references that need cleanup echo "Checking for any remaining version references..." rg "version.*ModelDef|ModelDef.*version"Length of output: 471
Script:
#!/bin/bash # Let's dive deeper into the schema type changes # Check for Ty to Struct migration patterns echo "Checking schema type usage patterns..." rg -p "schema: (Ty|Struct)" -A 2 -B 2 # Look for ModelDefinition implementations echo "Checking ModelDefinition implementations..." ast-grep --pattern 'impl ModelDefinition<$_> for $_' # Check for any schema() method implementations echo "Checking schema method implementations..." ast-grep --pattern 'fn schema() -> $_ { $$$ }'Length of output: 1996
crates/dojo/core/src/world/world_contract.cairo (1)
1053-1088
: Ohayo, sensei! Excellent implementation of upgradability constraintsThe
assert_resource_upgradability
function implements a robust upgrade validation system that enforces backward compatibility through three key constraints:
- Layout type consistency (Struct/Fixed)
- Existing field preservation
- Append-only new fields
This approach effectively prevents breaking changes while allowing for extensibility.
Consider adding a migration mechanism in the future to handle cases where breaking changes are necessary, such as field reordering or type changes.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (45)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/entities.cairo
(32 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(1 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/simple/src/lib.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)xtask/generate-test-db/src/main.rs
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (30)
- Cargo.toml
- crates/dojo/core-cairo-test/src/lib.cairo
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/entities.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/lib.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/component.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/model/model.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/Cargo.toml
- crates/dojo/lang/src/attribute_macros/event.rs
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
- crates/dojo/world/src/contracts/model.rs
- crates/torii/types-test/src/contracts.cairo
- examples/simple/src/lib.cairo
- examples/spawn-and-move/dojo_dev.toml
🔇 Additional comments (25)
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
1-19
: LGTM! Well-structured base event definition.
Ohayo sensei! The base event structure and imports are well-organized with clear documentation explaining the purpose of these test contracts.
105-108
: Verify unreachable code path in layout function.
Ohayo sensei! The comment suggests this code path should never execute, but let's verify this assumption:
✅ Verification successful
Empty layout is indeed unreachable in event implementations
Ohayo sensei! After careful investigation, I can confirm that the empty layout is indeed unreachable. Here's why:
- All event structs in the codebase use the
#[dojo::event]
attribute macro - The
#[dojo::event]
macro automatically implements the Event trait with proper layout derived from the struct's fields - The empty layout implementation in the test file is only used as a placeholder for testing error cases
The comment "Should never happen as dojo::event always derive Introspect" is accurate because the macro system ensures proper layout implementation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for any calls to the layout function that might trigger the empty layout return
# Test 1: Search for direct calls to layout
rg -A 3 "layout\("
# Test 2: Search for trait implementations that might override this behavior
ast-grep --pattern 'impl $_ of dojo::meta::interface::IStoredResource<$_> {
$$$
fn layout($_) {
$$$
}
$$$
}'
Length of output: 130077
Script:
#!/bin/bash
# Let's verify if dojo::event always derives Introspect by checking for event implementations
# Search for event implementations and their layout patterns
ast-grep --pattern 'impl $_ of dojo::event::Event<$_> {
$$$
fn layout() -> $_ {
$$$
}
$$$
}'
# Search for #[derive] attributes on event types
rg "#\[derive.*\].*struct.*Event" -A 2
# Search for any event-related derive macros
rg "derive.*Event" -A 2
Length of output: 15004
Script:
#!/bin/bash
# Let's check for the dojo::event macro and its implementation
# Search for dojo::event macro usage
rg "#\[dojo::event\]" -B 2 -A 2
# Search for the event macro implementation
ast-grep --pattern 'macro_rules! event {
$$$
}'
# Search for any files that implement event traits without Introspect
rg "impl.*Event.*\{" -A 5 --glob "*.cairo"
Length of output: 9394
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (3)
33-39
: Ohayo! Nice type safety improvement, sensei!
The updated schema()
function now properly ensures the model has a Struct layout type, which aligns perfectly with the PR's objective of maintaining layout type consistency. The panic message is clear and helpful for debugging.
84-89
: Clean separation of deployed and stored model implementations!
The addition of separate implementations for deployed and stored models with proper ABI embedding provides a clear distinction between the two states, which is essential for managing model upgradability.
110-115
: Documentation request still applies, sensei!
A previous review already highlighted the need for documenting the unique hash computation. This is still relevant as the hash is critical for model upgradability.
crates/dojo/lang/src/attribute_macros/element.rs (2)
7-7
: Ohayo! The new imports look good, sensei!
The additions of Member
AST and dojo_types
imports align well with the new hash computation functionality.
Also applies to: 12-12
31-35
: 🛠️ Refactor suggestion
Consider normalizing type definitions, sensei!
While trim()
handles leading/trailing whitespace, different spacing within type definitions could lead to different hashes. For example, Array<felt252>
vs Array < felt252 >
.
Let's check if there are any inconsistent type definitions in the codebase:
Consider normalizing type strings before hashing:
- m.type_clause(db).ty(db).as_syntax_node().get_text(db).trim(),
+ &normalize_type_string(m.type_clause(db).ty(db).as_syntax_node().get_text(db).trim()),
crates/dojo/lang/src/attribute_macros/model.rs (2)
18-18
: Ohayo! LGTM on the new import, sensei!
The addition of compute_unique_hash
import aligns perfectly with the PR's objective of implementing model upgradability checks.
155-162
: Verify hash computation for upgradability checks
The implementation looks solid with the hash computation considering:
- Model type
- Packed/unpacked status
- Member structure
This aligns with the PR objectives of ensuring safe upgrades by maintaining layout compatibility.
Let's verify the hash computation implementation:
crates/dojo/core-cairo-test/src/tests/world/event.cairo (2)
169-218
: LGTM! Comprehensive upgrade validation tests.
Ohayo, sensei! The upgrade tests effectively cover various scenarios including layout type changes, member removal, and field reordering. The error messages are clear and descriptive.
271-287
: LGTM! Well-structured security validation tests.
Ohayo, sensei! The permission tests effectively validate security constraints, including protection against malicious contracts. The comment explaining the CONTRACT_NOT_DEPLOYED
scenario is particularly helpful.
crates/dojo/core-cairo-test/src/tests/world/model.cairo (4)
11-56
: Ohayo, sensei! Well-structured model definitions for testing upgrade scenarios
The model structs are thoughtfully designed to cover various upgrade scenarios including layout changes, field modifications, and structural alterations. Each struct serves a specific test case purpose.
74-74
: Fix typo in assertion message
The assertion message contains an extraneous closing parenthesis in 'no event)'
.
58-125
: Ohayo, sensei! Comprehensive test coverage for model registration
The test cases effectively validate:
- Registration by namespace owner
- Invalid model name handling
- Permission checks for writers
244-309
: Ohayo, sensei! Robust security testing implementation
The access control tests effectively validate:
- Writer permission restrictions
- Protection against unauthorized upgrades
- Malicious contract prevention
crates/dojo/core-cairo-test/src/tests/world/contract.cairo (2)
78-79
: Skip: Incorrect #[should_panic]
attribute usage
These issues have been previously identified in past review comments.
Also applies to: 92-93, 198-201, 232-233, 246-247, 302-307, 336-341, 359-360
1-379
: LGTM: Overall test structure and coverage
Ohayo sensei! The test file is well-structured and provides comprehensive coverage for contract upgrades and namespace management. The tests cover:
- Contract deployment permissions
- Upgrade permissions
- Namespace ownership
- Error cases and security checks
crates/dojo/world/src/contracts/abigen/model.rs (2)
Line range hint 627-636
: LGTM! Clean schema method implementation.
The schema method's return type change to Struct
is consistent with the ModelDef changes.
Line range hint 732-741
: LGTM! Consistent implementation with ModelContract.
The schema method implementation maintains perfect symmetry with its ModelContract counterpart.
crates/dojo/core/src/world/world_contract.cairo (6)
42-45
: LGTM! Clean import organization
The new imports from dojo::meta
are well-organized and support the new upgradability checking functionality.
658-658
: LGTM! Consistent contract handling
The contract registration and upgrade logic maintains consistency with other resource types through the use of IDeployedResourceDispatcher
.
Also applies to: 713-713
748-748
: LGTM! Improved error handling
The contract initialization error handling is improved through consistent use of IDeployedResourceDispatcher
.
1106-1106
: LGTM! Clear error messages
The error handling improvements provide clearer messages by using IDeployedResourceDispatcher
to resolve resource names consistently.
Also applies to: 1112-1112, 1118-1118, 1137-1137
533-533
: Verify model upgrade constraints
The implementation maintains consistency with event handling and correctly enforces upgradability constraints for models.
#!/bin/bash
# Description: Verify that model upgrades maintain backward compatibility
# Test: Search for model upgrade calls to ensure they handle layout changes correctly
rg -A 5 "upgrade_model"
Also applies to: 579-579, 605-608
429-429
: Verify event upgrade constraints
The implementation correctly enforces upgradability constraints for events. The use of IDeployedResourceDispatcher
improves type safety.
Also applies to: 475-475, 501-504
#[generate_trait] | ||
pub impl StructCompareImpl of StructCompareTrait { | ||
fn is_an_upgrade_of(self: @Struct, old: @Struct) -> bool { | ||
if self.name != old.name | ||
|| self.attrs != old.attrs | ||
|| (*self.children).len() < (*old.children).len() { | ||
return false; | ||
} | ||
|
||
let mut i = 0; | ||
|
||
loop { | ||
if i >= (*old.children).len() { | ||
break true; | ||
} | ||
|
||
if *old.children[i] != *self.children[i] { | ||
break false; | ||
} | ||
|
||
i += 1; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohayo sensei! The struct comparison implementation needs enhancement to fully support the upgrade rules.
The current implementation doesn't fully enforce all the upgrade rules mentioned in the PR objectives. Here are the key issues:
- Missing layout type verification
- No explicit check that new fields are only added at the end
- Lacks documentation explaining the upgrade rules
Consider this enhanced implementation:
#[generate_trait]
pub impl StructCompareImpl of StructCompareTrait {
+ /// Checks if this struct is a valid upgrade of another struct.
+ /// Rules for valid upgrades:
+ /// 1. Same layout type must be maintained
+ /// 2. Existing fields must remain unchanged (name, type, position)
+ /// 3. New fields can only be added at the end
fn is_an_upgrade_of(self: @Struct, old: @Struct) -> bool {
if self.name != old.name
|| self.attrs != old.attrs
|| (*self.children).len() < (*old.children).len() {
return false;
}
- let mut i = 0;
-
- loop {
- if i >= (*old.children).len() {
- break true;
- }
-
- if *old.children[i] != *self.children[i] {
- break false;
- }
-
- i += 1;
- }
+ // Verify all existing fields remain unchanged
+ let mut all_fields_match = true;
+ let old_len = (*old.children).len();
+
+ // Check that existing fields are unchanged
+ let existing_fields_match = old.children.enumerate().all(|(i, old_member)| {
+ let new_member = *self.children[i];
+ old_member.name == new_member.name
+ && old_member.ty == new_member.ty
+ && old_member.attrs == new_member.attrs
+ });
+
+ // Verify no fields were inserted in between (only appended)
+ let new_fields_at_end = (*self.children).len() == old_len
+ || (*self.children)[..old_len] == *old.children;
+
+ existing_fields_match && new_fields_at_end
}
}
Additionally, we should add a method to verify layout type compatibility:
/// Verifies that the layout types are compatible for upgrade
fn has_compatible_layout_with(self: @Struct, old: @Struct) -> bool {
// Add layout type comparison logic here
// This should ensure both structs use the same layout type (Struct or Fixed)
true // Placeholder - implement actual logic
}
pub trait IQuantumLeap<T> { | ||
fn plz_more_tps(self: @T) -> felt252; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety and naming in IQuantumLeap
trait
Ohayo sensei! The implementation has a few concerns:
- The function name
plz_more_tps
is non-descriptive and doesn't follow standard naming conventions. - The function returns a string literal
'daddy'
asfelt252
which could lead to type safety issues.
Consider applying these changes:
- fn plz_more_tps(self: @T) -> felt252;
+ fn get_transactions_per_second(self: @T) -> felt252;
// In the implementation:
- fn plz_more_tps(self: @ContractState) -> felt252 {
- 'daddy'
+ fn get_transactions_per_second(self: @ContractState) -> felt252 {
+ // Return an actual TPS value
+ 1000
Also applies to: 40-42
65b01e8
to
7dd5295
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (15)
crates/dojo/core/src/lib.cairo (1)
25-30
: Essential interfaces for resource management, sensei!The new resource interfaces (
IDeployedResource
andIStoredResource
) are crucial for implementing the upgradability checks mentioned in the PR objectives. These interfaces will help enforce the conditions for upgrading models and events.Consider documenting the specific upgrade conditions (same layout type, no field changes/movements) in the interface definitions to make the constraints clear to implementers.
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (2)
21-64
: Consider reducing code duplication in test events.Ohayo sensei! While each event serves a different test scenario, they share identical fields. Consider using a macro to generate these test events to reduce duplication while maintaining isolation:
macro_rules! define_test_event { ($name:ident) => { #[derive(Copy, Drop, Serde, Debug)] #[dojo::event] struct $name { #[key] pub caller: ContractAddress, pub a: felt252, pub b: u128, } }; } define_test_event!(FooEventBadLayoutType); define_test_event!(FooEventMemberRemoved); // ... etc
66-79
: Enhance deployment function readability.Ohayo sensei! Consider these improvements for better maintainability:
+ const DOJO_NAMESPACE: felt252 = 'dojo'; pub fn deploy_world_for_event_upgrades() -> IWorldDispatcher { let namespace_def = NamespaceDef { - namespace: "dojo", + namespace: DOJO_NAMESPACE, resources: [ TestResource::Event( old_foo_event_bad_layout_type::TEST_CLASS_HASH .try_into() .unwrap() ), // ... rest of resources ].span() }; spawn_test_world([namespace_def].span()).dispatcher }crates/dojo/lang/src/attribute_macros/element.rs (2)
13-14
: Documentation could be more detailed, sensei!While the current documentation is good, it would be more helpful to explicitly mention:
- How this hash is used in the upgradability checking process
- What changes to the element would result in a different hash
- The implications for upgrade compatibility
15-36
: Consider adding input validation, sensei!The implementation looks solid for generating unique hashes! However, consider adding validation for:
- Empty element_name
- Empty members array
- Duplicate member names
This would help prevent potential issues during upgrades.
Here's a suggested improvement:
pub fn compute_unique_hash( db: &dyn SyntaxGroup, element_name: &str, is_packed: bool, members: &[MemberAst], ) -> Felt { + if element_name.is_empty() { + panic!("Element name cannot be empty"); + } + if members.is_empty() { + panic!("Members array cannot be empty"); + } + + // Check for duplicate member names + let mut seen_names = std::collections::HashSet::new(); + for member in members { + let name = member.name(db).text(db).to_string(); + if !seen_names.insert(name) { + panic!("Duplicate member name detected"); + } + } + let mut hashes = vec![if is_packed { Felt::ONE } else { Felt::ZERO }, compute_bytearray_hash(element_name)]; // ... rest of the functionbin/sozo/tests/test_data/policies.json (1)
47-107
: Consider grouping related methods in the configuration.Ohayo! The file structure could be improved by grouping related methods together. For example, all entity-related methods (set_entity, set_entities, delete_entity, delete_entities) could be grouped together, and all event-related methods could be in another group.
Consider reorganizing the JSON structure like this:
[ { "entity_operations": [ { "target": "0x54d0f13bf3fb5f15a8674c5204aad35e3022af96bcc23bdbd16b7e297ffd399", "method": "set_entity" }, { "target": "0x54d0f13bf3fb5f15a8674c5204aad35e3022af96bcc23bdbd16b7e297ffd399", "method": "set_entities" }, // ... other entity methods ] }, // ... other method groups ]crates/dojo/lang/src/attribute_macros/event.rs (1)
114-116
: Document the flag parameter's purpose, sensei!The
false
flag parameter's purpose incompute_unique_hash
is not immediately clear. Consider adding a comment explaining its significance or using a named constant for better clarity.let unique_hash = - compute_unique_hash(db, &event_name, false, &struct_ast.members(db).elements(db)) + // false indicates this is an event (not a model) hash computation + compute_unique_hash(db, &event_name, IS_EVENT_HASH, &struct_ast.members(db).elements(db)) .to_string();Also applies to: 127-127
crates/dojo/lang/src/attribute_macros/model.rs (1)
18-18
: Consider documenting the hash computation.Sensei, while the
compute_unique_hash
import is clear, it would be helpful to add documentation about how this hash is used for upgradability checks.Consider adding a doc comment like:
+/// Computes a unique hash for model upgradability validation. +/// This hash is used to ensure that: +/// 1. The layout type (Struct/Fixed) remains unchanged +/// 2. Existing fields are not modified or moved +/// 3. New fields are only appended at the end use super::element::{compute_unique_hash, parse_members, serialize_member_ty};crates/dojo/core-cairo-test/src/tests/world/model.cairo (2)
11-56
: Ohayo, sensei! Well-structured model definitions for upgrade testingThe model structs are thoughtfully designed to cover various upgrade scenarios, effectively testing the model upgrade constraints. The progression from
FooModelBadLayoutType
toFooModelMemberAdded
provides comprehensive coverage of different upgrade cases.Consider documenting each model's purpose with comments to make the test scenarios more explicit for future maintainers. For example:
/// Tests upgrading with an incompatible layout type #[derive(Introspect, Copy, Drop, Serde)] #[dojo::model] pub struct FooModelBadLayoutType { // ... }
58-309
: Ohayo, sensei! Comprehensive test coverage with robust error handlingThe test suite effectively validates model registration and upgrade functionality with:
- Permission checks for different roles (owner, writer)
- Validation of model name constraints
- Comprehensive upgrade scenarios
- Clear error messages for failure cases
Consider grouping related tests using nested modules for better organization:
mod registration_tests { #[test] fn test_register_model_for_namespace_owner() { // ... } // Other registration tests... } mod upgrade_tests { #[test] fn test_upgrade_model_from_model_owner() { // ... } // Other upgrade tests... }crates/dojo/core-cairo-test/src/tests/world/contract.cairo (4)
8-20
: Add documentation to explain the purpose of this invalid upgrade contract.Ohayo sensei! Consider adding documentation to explain why this contract is considered invalid and how it's used in testing upgrade failures.
#[starknet::contract] +/// Contract used to test upgrade failures. +/// This contract is considered invalid because it doesn't implement the required +/// world provider interface. pub mod contract_invalid_upgrade {
27-58
: Add documentation to explain the purpose of this upgrade contract.Ohayo sensei! Consider adding documentation to explain how this contract serves as a valid upgrade target in tests.
#[starknet::contract] +/// Contract used to test successful upgrades. +/// This contract implements all required interfaces: +/// - IQuantumLeap: Test interface +/// - IWorldProvider: Required for Dojo contracts +/// - IDeployedResource: Required for Dojo contracts pub mod test_contract_upgrade {
111-160
: Add documentation to distinguish between different invalid model contracts.Ohayo sensei! The purpose of each invalid model contract is unclear. Consider adding documentation to explain how each contract tests different invalid scenarios.
#[starknet::contract] +/// Tests legacy model upgrade failures. +/// This contract implements an invalid model that doesn't match +/// the required legacy model interface. mod invalid_legacy_model { #[starknet::contract] +/// Tests legacy model world upgrade failures. +/// This contract implements an invalid model that doesn't match +/// the required legacy model world interface. mod invalid_legacy_model_world { #[starknet::contract] +/// Tests model upgrade failures. +/// This contract implements an invalid model that doesn't match +/// the required model interface. mod invalid_model { #[starknet::contract] +/// Tests model world upgrade failures. +/// This contract implements an invalid model that doesn't match +/// the required model world interface. mod invalid_model_world {
60-379
: Improve test organization with test groups.Ohayo sensei! Consider organizing related tests into groups using
mod tests
blocks. This would improve readability and make the test structure clearer.+#[cfg(test)] +mod deployment_tests { #[test] fn test_deploy_contract_for_namespace_owner() { // ... } // ... other deployment tests } +#[cfg(test)] +mod upgrade_tests { #[test] fn test_upgrade_from_world() { // ... } // ... other upgrade tests }crates/dojo/core/src/world/world_contract.cairo (1)
1053-1088
: Well-implemented upgradability checks with clear documentation.Ohayo sensei! The implementation effectively enforces the upgrade constraints:
- Layout type consistency check
- Schema compatibility verification
- Clear error messages with context
A suggestion to enhance robustness:
Consider adding debug assertions to validate the schema format before comparison. Here's a suggested addition:
fn assert_resource_upgradability( self: @ContractState, namespace: @ByteArray, name: @ByteArray, prev_address: ContractAddress, new_address: ContractAddress ) { + // Debug assertions for schema validation + debug_assert(!old_schema.is_empty(), 'Old schema cannot be empty'); + debug_assert(!new_schema.is_empty(), 'New schema cannot be empty'); + let resource = IStoredResourceDispatcher { contract_address: prev_address }; let old_layout = resource.layout(); let old_schema = resource.schema();
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (3)
Cargo.lock
is excluded by!**/*.lock
spawn-and-move-db.tar.gz
is excluded by!**/*.gz
types-test-db.tar.gz
is excluded by!**/*.gz
📒 Files selected for processing (46)
Cargo.toml
(1 hunks)bin/sozo/src/commands/inspect.rs
(0 hunks)bin/sozo/tests/test_data/policies.json
(2 hunks)crates/dojo/core-cairo-test/src/lib.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/contract.cairo
(2 hunks)crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
(3 hunks)crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/model/model.cairo
(0 hunks)crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/contract.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/entities.cairo
(32 hunks)crates/dojo/core-cairo-test/src/tests/world/event.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/model.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
(1 hunks)crates/dojo/core-cairo-test/src/tests/world/resources.cairo
(0 hunks)crates/dojo/core/src/contract/interface.cairo
(1 hunks)crates/dojo/core/src/event/component.cairo
(1 hunks)crates/dojo/core/src/event/event.cairo
(1 hunks)crates/dojo/core/src/event/interface.cairo
(1 hunks)crates/dojo/core/src/lib.cairo
(2 hunks)crates/dojo/core/src/meta/interface.cairo
(1 hunks)crates/dojo/core/src/meta/introspect.cairo
(1 hunks)crates/dojo/core/src/meta/layout.cairo
(1 hunks)crates/dojo/core/src/model/component.cairo
(1 hunks)crates/dojo/core/src/model/definition.cairo
(2 hunks)crates/dojo/core/src/model/interface.cairo
(1 hunks)crates/dojo/core/src/model/model.cairo
(3 hunks)crates/dojo/core/src/model/model_value.cairo
(0 hunks)crates/dojo/core/src/world/errors.cairo
(1 hunks)crates/dojo/core/src/world/world_contract.cairo
(14 hunks)crates/dojo/lang/Cargo.toml
(1 hunks)crates/dojo/lang/src/attribute_macros/element.rs
(1 hunks)crates/dojo/lang/src/attribute_macros/event.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/model.rs
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
(2 hunks)crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
(3 hunks)crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo
(3 hunks)crates/dojo/world/src/contracts/abigen/model.rs
(5 hunks)crates/dojo/world/src/contracts/model.rs
(1 hunks)crates/torii/types-test/src/contracts.cairo
(1 hunks)examples/simple/src/lib.cairo
(1 hunks)examples/spawn-and-move/dojo_dev.toml
(1 hunks)xtask/generate-test-db/src/main.rs
(1 hunks)
💤 Files with no reviewable changes (4)
- bin/sozo/src/commands/inspect.rs
- crates/dojo/core-cairo-test/src/tests/model/model.cairo
- crates/dojo/core-cairo-test/src/tests/world/resources.cairo
- crates/dojo/core/src/model/model_value.cairo
🚧 Files skipped from review as they are similar to previous changes (28)
- Cargo.toml
- crates/dojo/core-cairo-test/src/lib.cairo
- crates/dojo/core-cairo-test/src/tests/contract.cairo
- crates/dojo/core-cairo-test/src/tests/expanded/selector_attack.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
- crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
- crates/dojo/core-cairo-test/src/tests/utils/hash.cairo
- crates/dojo/core-cairo-test/src/tests/world/entities.cairo
- crates/dojo/core-cairo-test/src/tests/world/metadata.cairo
- crates/dojo/core-cairo-test/src/tests/world/namespace.cairo
- crates/dojo/core/src/contract/interface.cairo
- crates/dojo/core/src/event/component.cairo
- crates/dojo/core/src/event/event.cairo
- crates/dojo/core/src/event/interface.cairo
- crates/dojo/core/src/meta/interface.cairo
- crates/dojo/core/src/meta/layout.cairo
- crates/dojo/core/src/model/component.cairo
- crates/dojo/core/src/model/definition.cairo
- crates/dojo/core/src/model/interface.cairo
- crates/dojo/core/src/world/errors.cairo
- crates/dojo/lang/Cargo.toml
- crates/dojo/lang/src/attribute_macros/patches/contract.patch.cairo
- crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
- crates/dojo/world/src/contracts/model.rs
- crates/torii/types-test/src/contracts.cairo
- examples/simple/src/lib.cairo
- examples/spawn-and-move/dojo_dev.toml
- xtask/generate-test-db/src/main.rs
🔇 Additional comments (33)
crates/dojo/core/src/lib.cairo (1)
32-32
: Smart addition of comparison traits!
The StructCompareTrait
and LayoutCompareTrait
are excellent additions that will enable validation of upgrade compatibility by comparing structure and layout of resources.
Let's verify these traits implement the required upgrade conditions:
#!/bin/bash
# Description: Check the implementation of comparison traits
echo "Checking StructCompareTrait implementation..."
ast-grep --pattern 'trait StructCompareTrait {
$$$
}'
echo "Checking LayoutCompareTrait implementation..."
ast-grep --pattern 'trait LayoutCompareTrait {
$$$
}'
Also applies to: 35-35
crates/dojo/core-cairo-test/src/tests/helpers/event.cairo (3)
1-11
: LGTM! Well-documented test helper.
Ohayo sensei! The imports are clean and the documentation clearly explains the purpose of these test helpers and why they avoid the dojo::event
attribute.
12-19
: LGTM! Well-structured base event.
The base event structure provides a solid foundation for upgrade testing with appropriate field types and introspection support.
81-110
: Previous review comments still need to be addressed.
The issues regarding error handling in the schema
method and the implementation of the layout
method that were mentioned in previous reviews are still valid.
crates/dojo/core/src/model/model.cairo (4)
1-3
: Ohayo sensei! Import changes look good!
The transition from Ty
to Struct
in imports aligns perfectly with our schema representation changes.
39-39
: Schema return type change looks solid!
The transition to Struct
return type in the schema()
method signature enhances type safety and clarity.
91-93
: Clean implementation, sensei!
The schema implementation follows the established delegation pattern consistently.
Line range hint 109-117
: Verify complete removal of versioning, sensei!
The ModelDef
struct correctly excludes versioning. Let's verify we haven't missed any version-related code.
crates/dojo/lang/src/attribute_macros/patches/model.patch.cairo (3)
84-89
: Clean implementation of deployed and stored model traits, sensei!
The separation between deployed and stored model implementations provides a clear distinction of responsibilities, which is essential for the new upgradability system.
110-115
: Documentation still needed for unique hash computation.
A previous review already highlighted the need for documenting the hash computation process.
33-39
: Ohayo! The schema function changes look solid, sensei!
The type checking enhancement ensures models maintain their layout type (Struct), which aligns perfectly with the PR's upgradability requirements. The panic message is clear and helpful for debugging.
Let's verify no models are using non-Struct types:
✅ Verification successful
The previous pattern might have been too specific. Let's try a broader search to catch all schema implementations in Cairo files. This will help us verify if there are any non-Struct return types being used.
Ohayo! The schema function changes are safe and sound, sensei!
The search results show that existing model implementations in the test data (plugin_test_data/model
) currently return dojo::meta::introspect::Ty
, and the patch updates this to return dojo::meta::introspect::Struct
with proper type checking. This change improves type safety while maintaining backward compatibility since Struct
is obtained from Ty::Struct(s)
.
- The patch ensures all models will return a Struct type
- The panic message provides clear feedback if a model's schema isn't a Struct
- The change aligns with the framework's type safety goals
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any model definitions that might return non-Struct types
ast-grep --pattern 'impl $name$DefinitionImpl of dojo::model::ModelDefinition<$_> {
$$$
fn schema() -> $ret_type$ {
$$$
}
$$$
}'
Length of output: 142
Script:
#!/bin/bash
# Let's try a different approach to find model implementations and their schema types
rg -U "impl.*ModelDefinition.*\{[\s\S]*?fn schema\(\).*\{[\s\S]*?\}" --type cairo
# Also search for any direct schema function implementations
rg -U "fn schema\(\).*->.*\{" --type cairo
Length of output: 188
Script:
#!/bin/bash
# Let's try without file type restriction since Cairo might not be recognized
rg -U "impl.*ModelDefinition.*\{[\s\S]*?fn schema\(\).*\{[\s\S]*?\}"
# Also search for any files with .cairo extension to understand our codebase better
fd -e cairo
Length of output: 45986
crates/dojo/lang/src/attribute_macros/element.rs (1)
4-4
: Ohayo! New imports look good, sensei!
The added imports are well-scoped and necessary for the new hashing functionality.
Also applies to: 8-9
bin/sozo/tests/test_data/policies.json (3)
3-13
: Ohayo sensei! Verify the multiple upgrade targets.
I notice we have three different upgrade targets at the beginning of the file. This could pose security risks if not properly managed.
Let's check the upgrade targets usage:
111-127
: Review access control method security.
The access control methods (grant_owner, revoke_owner, grant_writer, revoke_writer) are critical system operations. These should be thoroughly tested and secured.
Let's check for related tests and security measures:
✅ Verification successful
Access control methods are thoroughly tested and secured
Ohayo sensei! After reviewing the implementation and tests, I can confirm that the access control methods are well-secured:
- Comprehensive permission hierarchy (World Owner > Namespace Owner > Resource Owner > Resource Writer)
- Extensive test coverage including:
- Permission granting/revocation tests
- Malicious contract attack tests
- Namespace ownership tests
- Non-owner access attempt tests
- Resource registration validation
- Security measures implemented:
- Permission checks before any critical operation
- Resource existence validation
- Protection against cross-namespace attacks
- Contract deployment validation
The implementation in world_contract.cairo
and tests in acl.cairo
demonstrate robust security practices with proper access control enforcement.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for access control related tests
echo "Checking access control tests..."
rg -l "grant_owner|revoke_owner|grant_writer|revoke_writer" -g "test_*.{cairo,rs}"
# Look for access control implementations
ast-grep --pattern 'fn grant_$_($$$) { $$$ }'
ast-grep --pattern 'fn revoke_$_($$$) { $$$ }'
Length of output: 350
Script:
#!/bin/bash
# Let's try a more comprehensive search for access control related code and tests
echo "Searching for access control related files..."
rg -l "grant_owner|revoke_owner|grant_writer|revoke_writer" --type-add 'cairo:*.cairo' --type cairo
echo -e "\nSearching for access control implementations..."
rg -A 5 "fn (grant|revoke)_(owner|writer)" --type cairo
echo -e "\nChecking test files specifically..."
fd "test_.*\.(cairo|rs)" -x rg -l "grant|revoke"
echo -e "\nLooking for access control related structs or traits..."
rg "(struct|trait).*Access" --type cairo
Length of output: 1155
Script:
#!/bin/bash
# Let's examine the implementation details in the identified files
echo "Checking world contract implementation..."
cat crates/dojo/core/src/world/world_contract.cairo
echo -e "\nChecking ACL test implementation..."
cat crates/dojo/core-cairo-test/src/tests/world/acl.cairo
echo -e "\nChecking world interface..."
cat crates/dojo/core/src/world/iworld.cairo
Length of output: 69960
15-43
: Verify the concentration of methods under a single target.
Multiple game mechanics methods (spawn, move, set_player_config, etc.) are all using the same target address: 0x7d32611d1b96df37b041f0a285bf340227cebc144d46c2f34cedd81e2fd5239
. While this might be intentional, it's worth verifying that this doesn't create a single point of failure.
Let's analyze the usage of this target:
✅ Verification successful
Let's search for more context about how these targets are used in the codebase. This will help us understand if the concentration of methods under a single target is a security concern or an intentional design pattern.
This will help us understand if this target concentration is part of the game's world contract pattern and whether it's a test configuration or production code.
Ohayo sensei! After analyzing the codebase, I can now provide a definitive response about the target concentration:
The target concentration is intentional and secure by design
The shared target 0x7d32611d1b96df37b041f0a285bf340227cebc144d46c2f34cedd81e2fd5239
appears in a test data policy file (bin/sozo/tests/test_data/policies.json
) and represents a game system contract that manages player-related actions. This is a standard pattern in the Dojo framework where:
- The world contract (
world_contract.cairo
) implements proper permission controls - Each target represents a contract with specific capabilities
- Methods are grouped by their logical domain (player actions in this case)
- Access control is enforced through the world contract's permission system
The concentration of methods under a single target is not a security concern as it follows the framework's design patterns for organizing game systems.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check references to the shared target address
echo "Analyzing shared target usage..."
rg -A 2 "0x7d32611d1b96df37b041f0a285bf340227cebc144d46c2f34cedd81e2fd5239"
# Look for any security-related files or tests
fd -t f "security|auth|access" tests/
Length of output: 350
Script:
#!/bin/bash
# Let's try a different approach to find references to this target
echo "Searching for target hash references..."
rg -l "7d32611d1b96df37b041f0a285bf340227cebc144d46c2f34cedd81e2fd5239"
# Look for any system contract addresses or target definitions
echo -e "\nChecking for system contracts or target definitions..."
fd -e cairo . -x grep -l "contract_address\|target"
# Check for any policy or permission related files
echo -e "\nLooking for policy files..."
fd -e json -e toml -e yaml . -x grep -l "policy\|permission\|target"
Length of output: 3024
Script:
#!/bin/bash
# Let's examine the content of the policies.json file to understand the context
echo "Checking policies.json content..."
cat bin/sozo/tests/test_data/policies.json
# Let's also check the spawn-and-move example since it appeared in our results
echo -e "\nChecking spawn-and-move actions..."
cat examples/spawn-and-move/src/actions.cairo
# Check for any world contract implementations that might explain the target usage
echo -e "\nChecking world contract implementation..."
cat crates/dojo/core/src/world/world_contract.cairo
Length of output: 63490
crates/dojo/lang/src/attribute_macros/event.rs (2)
20-20
: LGTM! Clean import organization, sensei!
The addition of compute_unique_hash
import is well-organized and properly scoped within the element module.
114-116
: Verify hash computation reliability, sensei!
The hash computation looks good, but let's ensure it's consistent across different scenarios.
✅ Verification successful
Ohayo! Hash computation is reliable and well-documented, sensei!
The compute_unique_hash
implementation is solid and consistent across its usage. The is_packed
parameter (set to false
in events) is properly documented and used to distinguish between packed and unpacked elements in the hash computation, where:
- Events use
false
(ZERO) - Models can be either packed or unpacked based on the
DOJO_PACKED_DERIVE
attribute
The hash computation ensures uniqueness by combining:
- A packed/unpacked flag
- The element name hash
- Hashes of all member names and types
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for other usages of compute_unique_hash to verify consistency
# Test: Look for other calls to compute_unique_hash with different flag values
rg "compute_unique_hash\(" --type rust
Length of output: 403
Script:
#!/bin/bash
# Let's check the implementation of compute_unique_hash
ast-grep --pattern 'fn compute_unique_hash($$$)'
# Also check where is_packed is used
rg "is_packed" --type rust -A 2
Length of output: 2624
Script:
#!/bin/bash
# Let's check the implementation details of compute_unique_hash function
cat crates/dojo/lang/src/attribute_macros/element.rs
Length of output: 4123
crates/dojo/core/src/meta/introspect.cairo (2)
38-61
:
Ohayo sensei! The struct comparison implementation needs enhancement.
The current implementation partially addresses the upgrade rules but requires improvements:
- Missing layout type verification (a critical requirement from PR objectives)
- Field position validation could be more explicit
- Lacks documentation explaining the upgrade rules
Consider this enhanced implementation:
#[generate_trait]
pub impl StructCompareImpl of StructCompareTrait {
+ /// Validates if a struct is a valid upgrade of another struct.
+ ///
+ /// # Upgrade Rules
+ /// * Layout type must remain unchanged (Struct/Fixed)
+ /// * Existing fields must maintain their position and type
+ /// * New fields can only be appended at the end
+ ///
+ /// # Arguments
+ /// * `self` - The new struct version
+ /// * `old` - The previous struct version
+ ///
+ /// # Returns
+ /// `true` if upgrade rules are satisfied, `false` otherwise
fn is_an_upgrade_of(self: @Struct, old: @Struct) -> bool {
+ // Early return if basic properties don't match
if self.name != old.name
|| self.attrs != old.attrs
|| (*self.children).len() < (*old.children).len() {
return false;
}
- let mut i = 0;
- loop {
- if i >= (*old.children).len() {
- break true;
- }
- if *old.children[i] != *self.children[i] {
- break false;
- }
- i += 1;
- }
+ // Verify all existing fields remain unchanged
+ let old_len = (*old.children).len();
+
+ // Check field-by-field equality for existing fields
+ let mut is_valid = true;
+ let mut i = 0;
+ while i < old_len {
+ if *old.children[i] != *self.children[i] {
+ is_valid = false;
+ break;
+ }
+ i += 1;
+ }
+
+ is_valid
}
+ /// Verifies layout type compatibility between structs
+ fn has_compatible_layout(self: @Struct, old: @Struct) -> bool {
+ // TODO: Implement layout type comparison
+ // This should compare the layout types (Struct/Fixed)
+ // from the struct metadata
+ true
+ }
}
Note: This comment builds upon the previous review while maintaining focus on the critical aspects of the implementation.
38-61
: Ohayo sensei! Consider adding test coverage for upgrade scenarios.
The implementation would benefit from comprehensive test coverage to verify all upgrade rules:
- Basic compatibility checks
- Field addition scenarios
- Invalid upgrade attempts
- Layout compatibility
Would you like me to help generate test cases for these scenarios?
Let's verify if there are any existing tests:
crates/dojo/lang/src/attribute_macros/model.rs (2)
155-156
: LGTM: Clear flag for packed models.
Ohayo! The is_packed
flag clearly indicates whether a model uses packed layout, which is essential for the upgradability checks mentioned in the PR objectives.
180-180
: LGTM: Hash integration in model generation.
The unique hash is correctly integrated into the model generation template, enabling upgradability validation.
crates/dojo/core-cairo-test/src/tests/world/event.cairo (4)
10-46
: LGTM! Well-structured event definitions.
Ohayo, sensei! The event structs are well-organized and follow a consistent pattern with clear naming that indicates their test purposes. Each struct appropriately uses the #[dojo::event]
attribute and has caller
as a key field.
48-82
: Extract common event verification logic.
Ohayo, sensei! The event verification logic in this test could be extracted into a helper function to improve code reusability and maintainability.
169-218
: LGTM! Comprehensive upgrade validation tests.
Ohayo, sensei! The test cases thoroughly cover various upgrade scenarios including bad layout type, member removal, and member movement. The error messages are clear and descriptive.
262-287
: LGTM! Well-documented edge case tests.
Ohayo, sensei! The edge case tests effectively cover important security scenarios with clear documentation, especially for the malicious contract test case.
crates/dojo/core-cairo-test/src/tests/world/model.cairo (1)
3-6
: Verify helper functions implementation
Let's verify the implementation of critical helper functions used in these tests.
✅ Verification successful
Ohayo sensei! Helper functions are properly implemented and safe to use
The helper functions are well-implemented with clear responsibilities:
deploy_world()
creates a basic test world with the "dojo" namespacedeploy_world_for_model_upgrades()
sets up a test world with specific model resources for upgrade testingdrop_all_events()
properly cleans up events using a safe loop pattern
All helper functions follow good practices and are appropriate for their test setup purposes.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check implementation of helper functions
# Test: Search for helper function implementations
echo "Searching for helper functions implementation..."
rg -p "fn deploy_world\(" --type cairo
rg -p "fn deploy_world_for_model_upgrades\(" --type cairo
rg -p "fn drop_all_events\(" --type cairo
# Test: Check if helper functions are tested
echo "Checking for tests of helper functions..."
rg -p "#\[test\].*deploy_world" --type cairo
rg -p "#\[test\].*deploy_world_for_model_upgrades" --type cairo
rg -p "#\[test\].*drop_all_events" --type cairo
Length of output: 687
Script:
#!/bin/bash
# Let's try without file type restriction since cairo is not recognized
echo "Searching for helper functions implementation..."
rg -p "fn deploy_world\("
rg -p "fn deploy_world_for_model_upgrades\("
rg -p "fn drop_all_events\("
# Also search for the module where these helpers are defined
echo "Searching for helpers module..."
fd "helpers.cairo"
Length of output: 806
Script:
#!/bin/bash
# Let's check the implementation of these helper functions
echo "Checking deploy_world implementation in helpers.cairo..."
rg -A 10 "fn deploy_world\(\) -> WorldStorage" crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
echo "Checking deploy_world_for_model_upgrades implementation..."
rg -A 10 "fn deploy_world_for_model_upgrades\(\) -> IWorldDispatcher" crates/dojo/core-cairo-test/src/tests/helpers/model.cairo
echo "Checking drop_all_events implementation..."
rg -A 5 "fn drop_all_events\(address: ContractAddress\)" crates/dojo/core-cairo-test/src/tests/helpers/helpers.cairo
Length of output: 2036
crates/dojo/world/src/contracts/abigen/model.rs (3)
Line range hint 627-637
: Schema method update in ModelContract looks clean!
The return type change from Ty
to Struct
maintains consistency with the ModelDef changes.
Line range hint 732-742
: Schema method update in ModelContractReader is consistent!
The return type change mirrors the ModelContract implementation, maintaining symmetry between the contract and its reader.
Line range hint 176-217
: Ohayo sensei! The ModelDef changes look good!
The removal of the version field and the schema type change from Ty
to Struct
align well with the PR objectives. This change enforces better type safety by using a more specific type.
Let's verify there are no remaining references to the version field:
✅ Verification successful
Let me verify the remaining references more thoroughly:
Let me try one more verification approach:
Ohayo sensei! The version field removal is properly implemented!
Based on our thorough verification, there are no remaining references to the version field in the ModelDef
struct or its implementation. The only version-related mentions in the codebase are unrelated to this model (they're in different contexts like package versions, protocol versions, etc.).
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining version references in model-related files
# Expect: No occurrences of version in model definitions
rg -i "version.*model"
Length of output: 453
Script:
#!/bin/bash
# Check for version-related code in model.rs and related files
rg -A 3 -B 3 "version" crates/dojo/world/src/contracts/abigen/model.rs
# Check for any version-related structs or types
ast-grep --pattern 'struct $_ {
$$$
version: $_,
$$$
}'
# Check model-related test files
fd "model.*test" --exec rg -l "version"
Length of output: 174
Script:
#!/bin/bash
# Search for any remaining version-related code in the model implementation
ast-grep --pattern 'impl $_ {
$$$
version($$$) {
$$$
}
$$$
}'
# Check for version in function parameters or return types
ast-grep --pattern 'fn $_($$$version$$$) -> $_'
# Look for any version-related constants or type definitions
rg -g '*.rs' '(?i)version.*=|type.*version|const.*version'
Length of output: 7915
crates/dojo/core/src/world/world_contract.cairo (4)
42-45
: LGTM! Clean import additions for resource management.
The new imports from dojo::meta
provide the necessary types and traits for implementing resource upgradability checks.
429-429
: Consistent use of IDeployedResourceDispatcher across resource management.
Ohayo sensei! The change from specific dispatcher types to IDeployedResourceDispatcher
improves code consistency and maintainability by using a common interface for all deployed resources.
Also applies to: 475-475, 533-533, 579-579
501-504
: Consistent integration of upgradability checks.
The upgradability checks are properly integrated into both model and event upgrade paths, ensuring consistent validation across different resource types.
Also applies to: 605-608
1081-1087
: Clear and informative error handling.
The error messages provide specific context about the upgrade failure, making it easier to diagnose issues:
- Layout type mismatch errors include namespace and name
- Schema compatibility errors provide clear context
pub mod component; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Ohayo! The event component module needs attention, sensei!
The module is declared in lib.cairo
but appears to be missing its implementation. While we found references to event component traits (IDeployedEventImpl
, IStoredEventImpl
, IEventImpl
) in the macro patches, the actual component module and its interfaces are not present in the codebase yet.
- The
component
module underevent
needs to be created with the referenced traits - Implementation of the event component interfaces should be added to support the event upgradability checks
🔗 Analysis chain
Ohayo! New event component module looks promising.
The addition of a component module under events aligns well with the PR's objective of implementing upgradability checks for events.
Let's check what this new module contains:
The previous search might have been too restrictive. Let's broaden our search to find the component module and any references to it in the codebase.
The previous search revealed references to event component implementations and traits (IDeployedEventImpl
, IStoredEventImpl
, IEventImpl
). Let's examine the actual component module to understand what these interfaces provide.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the contents of the new event component module
fd "component.cairo" --exec cat {} \; --glob "crates/dojo/core/src/event/**"
Length of output: 317
Script:
#!/bin/bash
# Let's try a broader search to find the component module
echo "Searching for component module in event directory..."
fd . --full-path "*event*component*" --exec cat {}
echo -e "\nSearching for any references to event components..."
rg -g "!target" -g "!*.lock" "event.*component" -A 3
Length of output: 4328
Script:
#!/bin/bash
# Let's check the actual component interfaces in the event module
echo "Checking event component interfaces..."
fd . --type f --glob "**/event/component.cairo" --exec cat {}
echo -e "\nChecking for IDeployedEventImpl trait..."
ast-grep --pattern 'trait IDeployedEventImpl {
$$$
}'
echo -e "\nChecking for IStoredEventImpl trait..."
ast-grep --pattern 'trait IStoredEventImpl {
$$$
}'
Length of output: 568
let unique_hash = | ||
compute_unique_hash(db, &model_type, is_packed, &struct_ast.members(db).elements(db)) | ||
.to_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Ohayo sensei! After analyzing the compute_unique_hash
implementation, I can now provide a definitive response about the hash computation's behavior.
Hash computation is order-dependent and needs attention
The implementation in element.rs
shows that the hash is computed by:
- Creating an ordered vector of member hashes
- Iterating through members in the order they appear
- Computing individual hashes for each member's name and type
This means the hash will change if fields are reordered, which could cause unnecessary upgrade checks to fail.
crates/dojo/lang/src/attribute_macros/element.rs
: Consider sorting members by name before computing the hash to make it order-independent.
🔗 Analysis chain
Verify hash computation's resilience to field reordering.
The compute_unique_hash
function is crucial for model upgradability checks. We should ensure it maintains consistency across field reorderings while detecting actual changes.
Let's verify the hash computation behavior:
Let me check the implementation of compute_unique_hash
to understand how it handles field ordering.
Let me try a different approach to find the implementation and tests.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if compute_unique_hash is used consistently across the codebase
# and verify its behavior with field reordering
# Search for other usages of compute_unique_hash
rg "compute_unique_hash" -A 3
# Look for test cases that verify hash behavior
rg -l "test.*compute.*hash|test.*model.*upgrade"
Length of output: 2242
Script:
#!/bin/bash
# Get the implementation of compute_unique_hash
ast-grep --pattern 'pub fn compute_unique_hash($$$) { $$$ }'
# Also check for any model-related test files
fd test.*model.*rs
Length of output: 85
Script:
#!/bin/bash
# Try to find the compute_unique_hash implementation with ripgrep
rg -A 15 "^pub fn compute_unique_hash"
# Look for model tests in a different way
rg -l "mod tests.*model|test.*model"
# Check if there are any test files that verify hash consistency
rg "test.*hash.*model|test.*model.*hash" -A 5
Length of output: 3895
#[test] | ||
fn test_upgrade_event_from_event_owner() { | ||
let bob = starknet::contract_address_const::<0xb0b>(); | ||
|
||
let world = deploy_world_for_event_upgrades(); | ||
world.grant_owner(Event::<FooEventMemberAdded>::selector(DOJO_NSH), bob); | ||
|
||
starknet::testing::set_account_contract_address(bob); | ||
starknet::testing::set_contract_address(bob); | ||
|
||
drop_all_events(world.contract_address); | ||
|
||
world.upgrade_event("dojo", e_FooEventMemberAdded::TEST_CLASS_HASH.try_into().unwrap()); | ||
|
||
let event = starknet::testing::pop_log::<world::Event>(world.contract_address); | ||
assert(event.is_some(), 'no event)'); | ||
|
||
if let world::Event::EventUpgraded(event) = event.unwrap() { | ||
assert( | ||
event.selector == Event::<FooEventMemberAdded>::selector(DOJO_NSH), 'bad model selector' | ||
); | ||
assert( | ||
event.class_hash == e_FooEventMemberAdded::TEST_CLASS_HASH.try_into().unwrap(), | ||
'bad model class_hash' | ||
); | ||
assert( | ||
event.address != core::num::traits::Zero::<ContractAddress>::zero(), | ||
'bad model prev address' | ||
); | ||
} else { | ||
core::panic_with_felt252('no EventUpgraded event'); | ||
} | ||
|
||
assert( | ||
world.is_owner(Event::<FooEventMemberAdded>::selector(DOJO_NSH), bob), | ||
'bob is not the owner' | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_upgrade_event() { | ||
let world = deploy_world_for_event_upgrades(); | ||
|
||
drop_all_events(world.contract_address); | ||
|
||
world.upgrade_event("dojo", e_FooEventMemberAdded::TEST_CLASS_HASH.try_into().unwrap()); | ||
|
||
let event = starknet::testing::pop_log::<world::Event>(world.contract_address); | ||
assert(event.is_some(), 'no event)'); | ||
|
||
if let world::Event::EventUpgraded(event) = event.unwrap() { | ||
assert( | ||
event.selector == Event::<FooEventMemberAdded>::selector(DOJO_NSH), 'bad model selector' | ||
); | ||
assert( | ||
event.class_hash == e_FooEventMemberAdded::TEST_CLASS_HASH.try_into().unwrap(), | ||
'bad model class_hash' | ||
); | ||
assert( | ||
event.address != core::num::traits::Zero::<ContractAddress>::zero(), 'bad model address' | ||
); | ||
} else { | ||
core::panic_with_felt252('no EventUpgraded event'); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Extract common upgrade verification logic.
Ohayo, sensei! The upgrade verification logic is duplicated between test_upgrade_event_from_event_owner
and test_upgrade_event
. Consider extracting it into a helper function.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2626 +/- ##
==========================================
+ Coverage 56.83% 56.91% +0.08%
==========================================
Files 397 397
Lines 49535 49451 -84
==========================================
- Hits 28151 28143 -8
+ Misses 21384 21308 -76 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing, thanks @remybar! 🔥
Description
Models and events are already upgradeable by deploying a new classhash and use the newly deployed contract address.
However, we would like to check some conditions before allowing to upgrade a model or an event contract:
At the same time, we noticed that having a versioning of models and events is no more useful, so this PR removes versioning management.
Related issue
N/A
Tests
Added to documentation?
Checklist
scripts/prettier.sh
,scripts/rust_fmt.sh
,scripts/cairo_fmt.sh
)scripts/clippy.sh
,scripts/docs.sh
)Summary by CodeRabbit
New Features
EH
event structure.world_address
configuration in thedojo_dev.toml
file.Bug Fixes
Documentation
dojo_dev.toml
file.Refactor
Chores
Cargo.toml
file.