diff --git a/crates/dojo/core-cairo-test/src/tests/meta/introspect.cairo b/crates/dojo/core-cairo-test/src/tests/meta/introspect.cairo index 0a4950e795..df709ccab1 100644 --- a/crates/dojo/core-cairo-test/src/tests/meta/introspect.cairo +++ b/crates/dojo/core-cairo-test/src/tests/meta/introspect.cairo @@ -590,9 +590,152 @@ fn test_array_upgrade() { } #[test] -#[available_gas(259000)] +#[available_gas(300000)] fn test_primitive_upgrade_performance() { let gas = GasCounterTrait::start(); let _ = Ty::Primitive('ClassHash').is_an_upgrade_of(@Ty::Primitive('ContractAddress')); gas.end("Upgrade from ContractAddress to ClassHash"); } + +#[test] +fn test_key_member_upgrade() { + let s = Struct { + name: 's', + attrs: [].span(), + children: [ + Member { name: 'x', attrs: ['key'].span(), ty: Ty::Primitive('u8') }, + Member { + name: 'y', + attrs: ['key'].span(), + ty: Ty::Enum( + Enum { + name: 'e', + attrs: [].span(), + children: [('A', Ty::Primitive('u8')), ('B', Ty::Primitive('u16'))].span(), + }, + ), + }, + ] + .span(), + }; + + // primitive type + let mut upgraded = s; + upgraded + .children = + [Member { name: 'x', attrs: ['key'].span(), ty: Ty::Primitive('u128') }, *s.children[1]] + .span(); + + assert!(upgraded.is_an_upgrade_of(@s), "key primitive type upgrade"); + + // enum type + let mut upgraded = s; + upgraded + .children = + [ + *s.children[0], + Member { + name: 'y', + attrs: ['key'].span(), + ty: Ty::Enum( + Enum { + name: 'e', + attrs: [].span(), + children: [ + ('A', Ty::Primitive('u8')), ('B', Ty::Primitive('u16')), + ('C', Ty::Primitive('u32')), + ] + .span(), + }, + ), + }, + ] + .span(); + + assert!(upgraded.is_an_upgrade_of(@s), "key enum type upgrade"); + + // struct type (not allowed) + let s = Struct { + name: 's', + attrs: [].span(), + children: [ + Member { + name: 'x', + attrs: ['key'].span(), + ty: Ty::Struct(Struct { name: 'n', attrs: [].span(), children: [].span() }), + }, + ] + .span(), + }; + + let mut upgraded = s; + upgraded + .children = + [ + Member { + name: 'x', + attrs: ['key'].span(), + ty: Ty::Struct( + Struct { + name: 'n', + attrs: [].span(), + children: [ + Member { name: 'y', attrs: [].span(), ty: Ty::Primitive('u16') }, + ] + .span(), + }, + ), + }, + ] + .span(); + + assert!(!upgraded.is_an_upgrade_of(@s), "key struct type upgrade"); + + // array type (not allowed) + let s = Struct { + name: 's', + attrs: [].span(), + children: [ + Member { + name: 'x', attrs: ['key'].span(), ty: Ty::Array([Ty::Primitive('u8')].span()), + }, + ] + .span(), + }; + + let mut upgraded = s; + upgraded + .children = + [ + Member { + name: 'x', attrs: ['key'].span(), ty: Ty::Array([Ty::Primitive('u16')].span()), + }, + ] + .span(); + + assert!(!upgraded.is_an_upgrade_of(@s), "key array type upgrade"); + + // tuple type (not allowed) + let s = Struct { + name: 's', + attrs: [].span(), + children: [ + Member { + name: 'x', attrs: ['key'].span(), ty: Ty::Tuple([Ty::Primitive('u8')].span()), + }, + ] + .span(), + }; + + let mut upgraded = s; + upgraded + .children = + [ + Member { + name: 'x', attrs: ['key'].span(), ty: Ty::Tuple([Ty::Primitive('u16')].span()), + }, + ] + .span(); + + assert!(!upgraded.is_an_upgrade_of(@s), "key tuple type upgrade"); +} diff --git a/crates/dojo/core/src/meta/introspect.cairo b/crates/dojo/core/src/meta/introspect.cairo index a04cf1d7c8..ac05477647 100644 --- a/crates/dojo/core/src/meta/introspect.cairo +++ b/crates/dojo/core/src/meta/introspect.cairo @@ -292,7 +292,36 @@ impl StructCompareImpl of TyCompareTrait { impl MemberCompareImpl of TyCompareTrait { fn is_an_upgrade_of(self: @Member, old: @Member) -> bool { - self.name == old.name && self.attrs == old.attrs && self.ty.is_an_upgrade_of(old.ty) + if self.name != old.name || self.attrs != old.attrs { + return false; + } + + let mut i = 0; + let is_key = loop { + if i >= (*self).attrs.len() { + break false; + } + + if *self.attrs[i] == 'key' { + break true; + } + + i += 1; + }; + + if is_key { + match (self.ty, old.ty) { + (Ty::Primitive(n), Ty::Primitive(o)) => n.is_an_upgrade_of(o), + (Ty::Enum(n), Ty::Enum(o)) => n.is_an_upgrade_of(o), + (Ty::Struct(n), Ty::Struct(o)) => n == o, + (Ty::Array(n), Ty::Array(o)) => n == o, + (Ty::Tuple(n), Ty::Tuple(o)) => n == o, + (Ty::ByteArray, Ty::ByteArray) => true, + _ => false, + } + } else { + self.ty.is_an_upgrade_of(old.ty) + } } } diff --git a/examples/spawn-and-move/dojo_dev.toml b/examples/spawn-and-move/dojo_dev.toml index 2e0804b8f5..0d6fc08877 100644 --- a/examples/spawn-and-move/dojo_dev.toml +++ b/examples/spawn-and-move/dojo_dev.toml @@ -31,7 +31,7 @@ rpc_url = "http://localhost:5050/" # Default account for katana with seed = 0 account_address = "0x2af9427c5a277474c079a1283c880ee8a6f0f8fbf73ce969c08d88befec1bba" private_key = "0x1800000000300000180000000000030000000000003006001800006600" -world_address = "0x266989f02ff93895d29cf079b4e59d8140d459b90fcc46fa71ffa1023bff5f3" +world_address = "0x7dab3fce8fed0cef35d203d8b613a48ddd7700ac7e7a1ba4d8abec4b7c5b14" ipfs_config.url = "https://ipfs.infura.io:5001" ipfs_config.username = "2EBrzr7ZASQZKH32sl2xWauXPSA" ipfs_config.password = "12290b883db9138a8ae3363b6739d220" diff --git a/spawn-and-move-db.tar.gz b/spawn-and-move-db.tar.gz index df03981ecb..ff6e4bca25 100644 Binary files a/spawn-and-move-db.tar.gz and b/spawn-and-move-db.tar.gz differ diff --git a/types-test-db.tar.gz b/types-test-db.tar.gz index 655dee18ce..690989f2f6 100644 Binary files a/types-test-db.tar.gz and b/types-test-db.tar.gz differ