Skip to content

Commit

Permalink
update world auth
Browse files Browse the repository at this point in the history
  • Loading branch information
remybar committed Jun 8, 2024
1 parent 547fa48 commit 63edbfc
Show file tree
Hide file tree
Showing 56 changed files with 9,998 additions and 296 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/benches/contracts/src/tests/test_world.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod tests {
let mut models = array![position::TEST_CLASS_HASH, moves::TEST_CLASS_HASH];

// deploy world with models
let world = spawn_test_world(models);
let world = spawn_test_world("benches", models);

// deploy systems contract
let contract_address = world
Expand Down
38 changes: 36 additions & 2 deletions crates/dojo-core/src/base_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use contract_upgrade::{IQuantumLeapDispatcher, IQuantumLeapDispatcherTrait};

// Utils
fn deploy_world() -> IWorldDispatcher {
spawn_test_world(array![])
spawn_test_world("dojo", array![])
}

// A test contract needs to be used instead of previously used base contract since.
Expand Down Expand Up @@ -111,6 +111,8 @@ fn test_upgrade_direct() {
trait IMetadataOnly<T> {
fn selector(self: @T) -> felt252;
fn name(self: @T) -> ByteArray;
fn namespace(self: @T) -> ByteArray;
fn namespace_selector(self: @T) -> felt252;
}

#[starknet::contract]
Expand All @@ -125,6 +127,14 @@ mod invalid_legacy_model {
0x742c3d09472a40914dedcbd609788fd547bde613d6c4d4c2f15d41f4e241f25
}

fn namespace(self: @ContractState) -> ByteArray {
"dojo"
}

fn namespace_selector(self: @ContractState) -> felt252 {
dojo::utils::hash(@Self::namespace(self))
}

fn name(self: @ContractState) -> ByteArray {
"invalid_legacy_model"
}
Expand All @@ -144,6 +154,14 @@ mod invalid_legacy_model_world {
0
}

fn namespace(self: @ContractState) -> ByteArray {
"dojo"
}

fn namespace_selector(self: @ContractState) -> felt252 {
dojo::utils::hash(@Self::namespace(self))
}

fn name(self: @ContractState) -> ByteArray {
"invalid_legacy_model"
}
Expand All @@ -160,7 +178,15 @@ mod invalid_model {
fn selector(self: @ContractState) -> felt252 {
// NOTE: Need to update this value if address changes
// Pre-computed address of a contract deployed through the world.
0x42503befcd7ad05718645aca9c5ddd83b53dca440f9239ce2dcf63018fba16
0x60b3bc751486f95a16596f7f7346b37cf48b2137f1d7e7c9de11c31d0c40479
}

fn namespace(self: @ContractState) -> ByteArray {
"dojo"
}

fn namespace_selector(self: @ContractState) -> felt252 {
dojo::utils::hash(@Self::namespace(self))
}

fn name(self: @ContractState) -> ByteArray {
Expand All @@ -182,6 +208,14 @@ mod invalid_model_world {
0
}

fn namespace(self: @ContractState) -> ByteArray {
"dojo"
}

fn namespace_selector(self: @ContractState) -> felt252 {
dojo::utils::hash(@Self::namespace(self))
}

fn name(self: @ContractState) -> ByteArray {
"invalid_model_world"
}
Expand Down
3 changes: 3 additions & 0 deletions crates/dojo-core/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ mod packing_test;
mod world;
#[cfg(test)]
mod world_test;
mod utils;
#[cfg(test)]
mod utils_test;

// Since Scarb 2.6.0 there's an optimization that does not
// build tests for dependencies and it's not configurable.
Expand Down
7 changes: 5 additions & 2 deletions crates/dojo-core/src/model.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ trait Model<T> {
fn selector() -> felt252;
fn instance_selector(self: @T) -> felt252;
fn namespace() -> ByteArray;
fn namespace_selector() -> felt252;
fn keys(self: @T) -> Span<felt252>;
fn values(self: @T) -> Span<felt252>;
fn layout() -> dojo::database::introspect::Layout;
Expand All @@ -23,6 +24,7 @@ trait IModel<T> {
fn name(self: @T) -> ByteArray;
fn version(self: @T) -> u8;
fn namespace(self: @T) -> ByteArray;
fn namespace_selector(self: @T) -> felt252;
fn unpacked_size(self: @T) -> Option<usize>;
fn packed_size(self: @T) -> Option<usize>;
fn layout(self: @T) -> dojo::database::introspect::Layout;
Expand All @@ -38,13 +40,14 @@ trait IModel<T> {
/// * `class_hash` - Class Hash of the model.
fn deploy_and_get_metadata(
salt: felt252, class_hash: starknet::ClassHash
) -> SyscallResult<(starknet::ContractAddress, ByteArray, felt252, ByteArray)> {
) -> SyscallResult<(starknet::ContractAddress, ByteArray, felt252, ByteArray, felt252)> {
let (contract_address, _) = starknet::deploy_syscall(
class_hash, salt, array![].span(), false,
)?;
let model = IModelDispatcher { contract_address };
let name = model.name();
let selector = model.selector();
let namespace = model.namespace();
Result::Ok((contract_address, name, selector, namespace))
let namespace_selector = model.namespace_selector();
Result::Ok((contract_address, name, selector, namespace, namespace_selector))
}
3 changes: 0 additions & 3 deletions crates/dojo-core/src/packing_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,6 @@ fn test_pack_with_offset() {

assert!(packed.len() == 2, "bad packed length");

println!("first item: {}", *packed.at(0));
println!("second item: {}", *packed.at(1));

assert!(*packed.at(0) == 0x70006, "bad packed first item");
assert!(*packed.at(1) == 0x0900000000000000000000000000000008, "bad packed second item");
}
Expand Down
19 changes: 9 additions & 10 deletions crates/dojo-core/src/resource_metadata.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
//! Manually expand to ensure that dojo-core
//! does not depend on dojo plugin to be built.
//!
use dojo::world::{IWorldDispatcherTrait, DOJO_NAMESPACE_SELECTOR};

use dojo::world::{IWorldDispatcherTrait};
use dojo::model::Model;

const RESOURCE_METADATA_SELECTOR: felt252 = selector!("ResourceMetadata");

fn initial_address() -> starknet::ContractAddress {
starknet::contract_address_const::<0>()
}
Expand All @@ -19,7 +16,7 @@ fn initial_class_hash() -> starknet::ClassHash {
>()
}

#[derive(Drop, Serde, PartialEq, Clone)]
#[derive(Drop, Serde, PartialEq, Clone, Debug)]
struct ResourceMetadata {
// #[key]
resource_id: felt252,
Expand All @@ -32,7 +29,7 @@ impl ResourceMetadataModel of dojo::model::Model<ResourceMetadata> {
keys: Span<felt252>,
layout: dojo::database::introspect::Layout
) -> ResourceMetadata {
let values = world.entity(RESOURCE_METADATA_SELECTOR, keys, layout);
let values = world.entity(Self::selector(), keys, layout);
let mut serialized = core::array::ArrayTrait::new();
core::array::serialize_array_helper(keys, ref serialized);
core::array::serialize_array_helper(values, ref serialized);
Expand Down Expand Up @@ -61,7 +58,7 @@ impl ResourceMetadataModel of dojo::model::Model<ResourceMetadata> {
#[inline(always)]
fn selector() -> felt252 {
poseidon::poseidon_hash_span(
array![DOJO_NAMESPACE_SELECTOR, RESOURCE_METADATA_SELECTOR].span()
array![Self::namespace_selector(), selector!("ResourceMetadata")].span()
)
}

Expand All @@ -71,8 +68,11 @@ impl ResourceMetadataModel of dojo::model::Model<ResourceMetadata> {
}

fn namespace() -> ByteArray {
// TODO: in future Cairo versions, it should be possible to create const ByteArray
"Dojo"
"__DOJO__"
}

fn namespace_selector() -> felt252 {
dojo::utils::hash(@Self::namespace())
}

#[inline(always)]
Expand Down Expand Up @@ -152,7 +152,6 @@ impl ResourceMetadataIntrospect<> of dojo::database::introspect::Introspect<Reso
mod resource_metadata {
use super::ResourceMetadata;
use super::ResourceMetadataModel;
use super::RESOURCE_METADATA_SELECTOR;

#[storage]
struct Storage {}
Expand Down
5 changes: 4 additions & 1 deletion crates/dojo-core/src/test_utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn deploy_with_world_address(class_hash: felt252, world: IWorldDispatcher) -> Co
deploy_contract(class_hash, array![world.contract_address.into()].span())
}

fn spawn_test_world(models: Array<felt252>) -> IWorldDispatcher {
fn spawn_test_world(namespace: ByteArray, models: Array<felt252>) -> IWorldDispatcher {
let salt = testing::get_available_gas();

// deploy world
Expand All @@ -54,6 +54,9 @@ fn spawn_test_world(models: Array<felt252>) -> IWorldDispatcher {

let world = IWorldDispatcher { contract_address: world_address };

// register namespace
world.register_namespace(namespace);

// register models
let mut index = 0;
loop {
Expand Down
6 changes: 6 additions & 0 deletions crates/dojo-core/src/utils.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// Compute the poseidon hash of a serialized ByteArray
fn hash(data: @ByteArray) -> felt252 {
let mut serialized = ArrayTrait::new();
Serde::serialize(data, ref serialized);
poseidon::poseidon_hash_span(serialized.span())
}
17 changes: 17 additions & 0 deletions crates/dojo-core/src/utils_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#[derive(Drop, Copy, Serde)]
#[dojo::model(namespace: "my namespace")]
struct MyModel {
#[key]
x: u8,
y: u8
}

#[test]
fn test_hash_computation() {
// Be sure that the namespace hash computed in `dojo-lang` in Rust is equal
// to the one computed in Cairo by dojo::utils:hash
let namespace = dojo::model::Model::<MyModel>::namespace();
let namespace_selector = dojo::model::Model::<MyModel>::namespace_selector();

assert(dojo::utils::hash(@namespace) == namespace_selector, 'invalid computed hash');
}
Loading

0 comments on commit 63edbfc

Please sign in to comment.