Skip to content

Commit

Permalink
feat: improve world contract performance (#2287)
Browse files Browse the repository at this point in the history
* add benchmarks

* split multi-conditions if into several single-condition if

* replace array![...].span() by [...].span()

* fix: add better error message for unregister models + merge

---------

Co-authored-by: glihm <dev@glihm.net>
  • Loading branch information
remybar and glihm authored Aug 14, 2024
1 parent a9b0bc5 commit 00770bd
Show file tree
Hide file tree
Showing 46 changed files with 519 additions and 408 deletions.
2 changes: 1 addition & 1 deletion crates/dojo-core/src/contract/upgradeable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub mod upgradeable {
assert(new_class_hash.is_non_zero(), Errors::INVALID_CLASS);

match starknet::syscalls::library_call_syscall(
new_class_hash, selector!("world"), array![].span(),
new_class_hash, selector!("world"), [].span(),
) {
Result::Ok(_) => {
replace_class_syscall(new_class_hash).unwrap();
Expand Down
55 changes: 25 additions & 30 deletions crates/dojo-core/src/model/introspect.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub impl Introspect_felt252 of Introspect<felt252> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('felt252')
Expand All @@ -57,7 +57,7 @@ pub impl Introspect_bool of Introspect<bool> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![1].span())
Layout::Fixed([1].span())
}
fn ty() -> Ty {
Ty::Primitive('bool')
Expand All @@ -69,7 +69,7 @@ pub impl Introspect_u8 of Introspect<u8> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![8].span())
Layout::Fixed([8].span())
}
fn ty() -> Ty {
Ty::Primitive('u8')
Expand All @@ -81,7 +81,7 @@ pub impl Introspect_u16 of Introspect<u16> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![16].span())
Layout::Fixed([16].span())
}
fn ty() -> Ty {
Ty::Primitive('u16')
Expand All @@ -93,7 +93,7 @@ pub impl Introspect_u32 of Introspect<u32> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![32].span())
Layout::Fixed([32].span())
}
fn ty() -> Ty {
Ty::Primitive('u32')
Expand All @@ -105,7 +105,7 @@ pub impl Introspect_u64 of Introspect<u64> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![64].span())
Layout::Fixed([64].span())
}
fn ty() -> Ty {
Ty::Primitive('u64')
Expand All @@ -117,7 +117,7 @@ pub impl Introspect_u128 of Introspect<u128> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![128].span())
Layout::Fixed([128].span())
}
fn ty() -> Ty {
Ty::Primitive('u128')
Expand All @@ -129,7 +129,7 @@ pub impl Introspect_u256 of Introspect<u256> {
Option::Some(2)
}
fn layout() -> Layout {
Layout::Fixed(array![128, 128].span())
Layout::Fixed([128, 128].span())
}
fn ty() -> Ty {
Ty::Primitive('u256')
Expand All @@ -141,7 +141,7 @@ pub impl Introspect_i8 of Introspect<i8> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('i8')
Expand All @@ -153,7 +153,7 @@ pub impl Introspect_i16 of Introspect<i16> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('i16')
Expand All @@ -165,7 +165,7 @@ pub impl Introspect_i32 of Introspect<i32> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('i32')
Expand All @@ -177,7 +177,7 @@ pub impl Introspect_i64 of Introspect<i64> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('i64')
Expand All @@ -189,7 +189,7 @@ pub impl Introspect_i128 of Introspect<i128> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('i128')
Expand All @@ -201,7 +201,7 @@ pub impl Introspect_address of Introspect<starknet::ContractAddress> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('starknet::ContractAddress')
Expand All @@ -213,7 +213,7 @@ pub impl Introspect_classhash of Introspect<starknet::ClassHash> {
Option::Some(1)
}
fn layout() -> Layout {
Layout::Fixed(array![251].span())
Layout::Fixed([251].span())
}
fn ty() -> Ty {
Ty::Primitive('starknet::ClassHash')
Expand All @@ -239,26 +239,21 @@ pub impl Introspect_option<T, +Introspect<T>> of Introspect<Option<T>> {

fn layout() -> Layout {
Layout::Enum(
array![
[
dojo::model::FieldLayout { // Some
selector: 0, layout: Introspect::<T>::layout() },
dojo::model::FieldLayout { // None
selector: 1, layout: Layout::Fixed(array![].span())
},
]
.span()
selector: 1, layout: Layout::Fixed([].span()) },
].span()
)
}

fn ty() -> Ty {
Ty::Enum(
Enum {
name: 'Option<T>',
attrs: array![].span(),
children: array![
('Some(T)', Introspect::<T>::ty()), ('None', Ty::Tuple(array![].span()))
]
.span()
name: 'Option<T>', attrs: [].span(), children: [
('Some(T)', Introspect::<T>::ty()), ('None', Ty::Tuple([].span()))
].span()
}
)
}
Expand All @@ -269,11 +264,11 @@ pub impl Introspect_array<T, +Introspect<T>> of Introspect<Array<T>> {
Option::None
}
fn layout() -> Layout {
Layout::Array(array![Introspect::<T>::layout()].span())
Layout::Array([Introspect::<T>::layout()].span())
}

fn ty() -> Ty {
Ty::Array(array![Introspect::<T>::ty()].span())
Ty::Array([Introspect::<T>::ty()].span())
}
}

Expand All @@ -282,10 +277,10 @@ pub impl Introspect_span<T, +Introspect<T>> of Introspect<Span<T>> {
Option::None
}
fn layout() -> Layout {
Layout::Array(array![Introspect::<T>::layout()].span())
Layout::Array([Introspect::<T>::layout()].span())
}

fn ty() -> Ty {
Ty::Array(array![Introspect::<T>::ty()].span())
Ty::Array([Introspect::<T>::ty()].span())
}
}
18 changes: 6 additions & 12 deletions crates/dojo-core/src/model/metadata.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub impl ResourceMetadataModel of Model<ResourceMetadata> {

#[inline(always)]
fn selector() -> felt252 {
poseidon_hash_span(array![Self::namespace_hash(), Self::name_hash()].span())
poseidon_hash_span([Self::namespace_hash(), Self::name_hash()].span())
}

#[inline(always)]
Expand Down Expand Up @@ -174,26 +174,20 @@ pub impl ResourceMetadataIntrospect<> of Introspect<ResourceMetadata<>> {
#[inline(always)]
fn layout() -> Layout {
Layout::Struct(
array![FieldLayout { selector: selector!("metadata_uri"), layout: Layout::ByteArray }]
.span()
[FieldLayout { selector: selector!("metadata_uri"), layout: Layout::ByteArray }].span()
)
}

#[inline(always)]
fn ty() -> Ty {
Ty::Struct(
Struct {
name: 'ResourceMetadata',
attrs: array![].span(),
children: array![
name: 'ResourceMetadata', attrs: [].span(), children: [
Member {
name: 'resource_id',
ty: Ty::Primitive('felt252'),
attrs: array!['key'].span()
name: 'resource_id', ty: Ty::Primitive('felt252'), attrs: ['key'].span()
},
Member { name: 'metadata_uri', ty: Ty::ByteArray, attrs: array![].span() }
]
.span()
Member { name: 'metadata_uri', ty: Ty::ByteArray, attrs: [].span() }
].span()
}
)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/dojo-core/src/model/model.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub fn deploy_and_get_metadata(
salt: felt252, class_hash: starknet::ClassHash
) -> SyscallResult<(starknet::ContractAddress, ByteArray, felt252, ByteArray, felt252)> {
let (contract_address, _) = starknet::syscalls::deploy_syscall(
class_hash, salt, array![].span(), false,
class_hash, salt, [].span(), false,
)?;
let model = IModelDispatcher { contract_address };
let name = model.name();
Expand Down
2 changes: 1 addition & 1 deletion crates/dojo-core/src/storage/database.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn fill_with_zeroes(ref values: Array<felt252>, size: u32) {
/// # Returns
/// A [`Span<felt252>`] representing an internal storage key.
fn get_storage_key(table: felt252, key: felt252) -> Span<felt252> {
array![DOJO_STORAGE, table, key].span()
[DOJO_STORAGE, table, key].span()
}

/// Read a record from a table, with its ID and layout.
Expand Down
18 changes: 9 additions & 9 deletions crates/dojo-core/src/storage/layout.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub fn write_array_layout(
let array_len: u32 = array_len.try_into().unwrap();

// then, write the array size
database::set(model, key, values, offset, array![251].span());
database::set(model, key, values, offset, [251].span());
offset += 1;

// and then, write array items
Expand Down Expand Up @@ -172,7 +172,7 @@ pub fn write_enum_layout(
assert(variant.into() < 256_u256, 'invalid variant value');

// and write it
database::set(model, key, values, offset, array![251].span());
database::set(model, key, values, offset, [251].span());
offset += 1;

// find the corresponding layout and then write the full variant
Expand Down Expand Up @@ -201,7 +201,7 @@ pub fn delete_fixed_layout(model: felt252, key: felt252, layout: Span<u8>) {
/// * `key` - the model record key.
pub fn delete_array_layout(model: felt252, key: felt252) {
// just set the array length to 0
database::delete(model, key, array![251].span());
database::delete(model, key, [251].span());
}

///
Expand All @@ -215,7 +215,7 @@ pub fn delete_byte_array_layout(model: felt252, key: felt252) {
//

// So, just set the 3 first values to 0 (len(data), pending_world and pending_word_len)
database::delete(model, key, array![251, 251, 251].span());
database::delete(model, key, [251, 251, 251].span());
}

/// Delete a model record from the world storage.
Expand Down Expand Up @@ -281,14 +281,14 @@ pub fn delete_tuple_layout(model: felt252, key: felt252, layout: Span<Layout>) {

pub fn delete_enum_layout(model: felt252, key: felt252, variant_layouts: Span<FieldLayout>) {
// read the variant value
let res = database::get(model, key, array![251].span());
let res = database::get(model, key, [251].span());
assert(res.len() == 1, 'internal database error');

let variant = *res.at(0);
assert(variant.into() < 256_u256, 'invalid variant value');

// reset the variant value
database::delete(model, key, array![251].span());
database::delete(model, key, [251].span());

// find the corresponding layout and the delete the full variant
let variant_data_key = combine_key(key, variant);
Expand Down Expand Up @@ -342,7 +342,7 @@ pub fn read_array_layout(
model: felt252, key: felt252, ref read_data: Array<felt252>, layout: Span<Layout>
) {
// read number of array items
let res = database::get(model, key, array![251].span());
let res = database::get(model, key, [251].span());
assert(res.len() == 1, 'internal database error');

let array_len = *res.at(0);
Expand Down Expand Up @@ -377,7 +377,7 @@ pub fn read_byte_array_layout(model: felt252, key: felt252, ref read_data: Array
//
// So, read the length of data and compute the full size to read

let res = database::get(model, key, array![251].span());
let res = database::get(model, key, [251].span());
assert(res.len() == 1, 'internal database error');

let data_len = *res.at(0);
Expand Down Expand Up @@ -445,7 +445,7 @@ pub fn read_enum_layout(
model: felt252, key: felt252, ref read_data: Array<felt252>, variant_layouts: Span<FieldLayout>
) {
// read the variant value first
let res = database::get(model, key, array![8].span());
let res = database::get(model, key, [8].span());
assert(res.len() == 1, 'internal database error');

let variant = *res.at(0);
Expand Down
4 changes: 2 additions & 2 deletions crates/dojo-core/src/storage/storage.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub fn get_packed_array(
address_domain: u32, keys: Span<felt252>, array_size: u32
) -> SyscallResult<Span<felt252>> {
if array_size == 0 {
return SyscallResult::<Span<felt252>>::Ok(array![].span());
return SyscallResult::<Span<felt252>>::Ok([].span());
}

let base = storage_base_address_from_felt252(poseidon_hash_span(keys));
Expand Down Expand Up @@ -221,6 +221,6 @@ pub fn get_packed_array(
}

fn chunk_segment_pointer(address: StorageAddress, chunk: felt252) -> StorageBaseAddress {
let p = poseidon_hash_span(array![address.into(), chunk, 'DojoStorageChunk'].span());
let p = poseidon_hash_span([address.into(), chunk, 'DojoStorageChunk'].span());
storage_base_address_from_felt252(p)
}
Loading

0 comments on commit 00770bd

Please sign in to comment.