From dd80c15684619f41299042eb31fd6e60a4b26c74 Mon Sep 17 00:00:00 2001 From: TAdev0 Date: Wed, 10 Apr 2024 19:20:40 +0200 Subject: [PATCH 1/5] first draft --- onchain/src/art_peace.cairo | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/onchain/src/art_peace.cairo b/onchain/src/art_peace.cairo index 11f79653..477081c1 100644 --- a/onchain/src/art_peace.cairo +++ b/onchain/src/art_peace.cairo @@ -1,6 +1,8 @@ #[starknet::contract] pub mod ArtPeace { use starknet::ContractAddress; + use starknet::info::get_block_timestamp; + use starknet::syscalls::get_execution_info_syscall; use art_peace::{IArtPeace, Pixel}; use art_peace::quests::{IQuestDispatcher, IQuestDispatcherTrait}; use art_peace::templates::component::TemplateStoreComponent; @@ -29,6 +31,7 @@ pub mod ArtPeace { creation_time: u64, end_time: u64, day_index: u32, + start_day_time: u64, // Map: (day_index, quest_id) -> quest contract address daily_quests: LegacyMap::<(u32, u32), ContractAddress>, main_quests_count: u32, @@ -43,11 +46,18 @@ pub mod ArtPeace { #[event] #[derive(Drop, starknet::Event)] enum Event { + Newday: NewDay, PixelPlaced: PixelPlaced, #[flat] TemplateEvent: TemplateStoreComponent::Event, } + #[derive(Drop, starknet::Event)] + struct NewDay { + #[key] + day_index: u32, + } + #[derive(Drop, starknet::Event)] struct PixelPlaced { #[key] @@ -71,6 +81,8 @@ pub mod ArtPeace { pub main_quests: Span, } + const day_time: u64 = consteval_int!(60 * 60 * 24); + #[constructor] fn constructor(ref self: ContractState, init_params: InitParams) { self.canvas_width.write(init_params.canvas_width); @@ -424,4 +436,19 @@ pub mod ArtPeace { } } } + + #[generate_trait] + impl InternatImpl of InternalTrait { + fn increase_day_index(ref self: ContractState) { + let block_timestamp = get_block_timestamp(); + let start_day_time = self.start_day_time.read(); + + if block_timestamp > start_day_time + day_time { + self.day_index.write(self.day_index.read() + 1); + self.start_day_time.write(block_timestamp); + + self.emit(NewDay { day_index: self.day_index.read() }); + } + } + } } From dabfd66008b91afe7b0ee9c584181a446e8ab8a8 Mon Sep 17 00:00:00 2001 From: TAdev0 Date: Wed, 10 Apr 2024 19:22:42 +0200 Subject: [PATCH 2/5] remove_uncessary_syscall_import --- onchain/src/art_peace.cairo | 1 - 1 file changed, 1 deletion(-) diff --git a/onchain/src/art_peace.cairo b/onchain/src/art_peace.cairo index 477081c1..f3e33c75 100644 --- a/onchain/src/art_peace.cairo +++ b/onchain/src/art_peace.cairo @@ -2,7 +2,6 @@ pub mod ArtPeace { use starknet::ContractAddress; use starknet::info::get_block_timestamp; - use starknet::syscalls::get_execution_info_syscall; use art_peace::{IArtPeace, Pixel}; use art_peace::quests::{IQuestDispatcher, IQuestDispatcherTrait}; use art_peace::templates::component::TemplateStoreComponent; From 1611a38623aadfc3a3c0512f3fb04653fdcb0575 Mon Sep 17 00:00:00 2001 From: TAdev0 Date: Wed, 10 Apr 2024 21:23:42 +0200 Subject: [PATCH 3/5] update --- onchain/src/art_peace.cairo | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/onchain/src/art_peace.cairo b/onchain/src/art_peace.cairo index f3e33c75..554980ac 100644 --- a/onchain/src/art_peace.cairo +++ b/onchain/src/art_peace.cairo @@ -1,7 +1,6 @@ #[starknet::contract] pub mod ArtPeace { use starknet::ContractAddress; - use starknet::info::get_block_timestamp; use art_peace::{IArtPeace, Pixel}; use art_peace::quests::{IQuestDispatcher, IQuestDispatcherTrait}; use art_peace::templates::component::TemplateStoreComponent; @@ -99,6 +98,7 @@ pub mod ArtPeace { }; self.creation_time.write(starknet::get_block_timestamp()); + self.start_day_time.write(starknet::get_block_timestamp()); self.end_time.write(init_params.end_time); self.day_index.write(0); @@ -439,15 +439,15 @@ pub mod ArtPeace { #[generate_trait] impl InternatImpl of InternalTrait { fn increase_day_index(ref self: ContractState) { - let block_timestamp = get_block_timestamp(); + let block_timestamp = starknet::get_block_timestamp(); let start_day_time = self.start_day_time.read(); - if block_timestamp > start_day_time + day_time { - self.day_index.write(self.day_index.read() + 1); - self.start_day_time.write(block_timestamp); + assert(block_timestamp > start_day_time + day_time, 'day has not passed'); - self.emit(NewDay { day_index: self.day_index.read() }); - } + self.day_index.write(self.day_index.read() + 1); + self.start_day_time.write(block_timestamp); + self.emit(NewDay { day_index: self.day_index.read() }); } } } + From 66a31f08dc1174724b47bfc159ed7e8e171f20a3 Mon Sep 17 00:00:00 2001 From: TAdev0 Date: Wed, 10 Apr 2024 21:26:32 +0200 Subject: [PATCH 4/5] make increase_day_index public --- onchain/src/art_peace.cairo | 25 +++++++++++-------------- onchain/src/interface.cairo | 3 +++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/onchain/src/art_peace.cairo b/onchain/src/art_peace.cairo index 554980ac..1f276251 100644 --- a/onchain/src/art_peace.cairo +++ b/onchain/src/art_peace.cairo @@ -357,6 +357,17 @@ pub mod ArtPeace { } } + fn increase_day_index(ref self: ContractState) { + let block_timestamp = starknet::get_block_timestamp(); + let start_day_time = self.start_day_time.read(); + + assert(block_timestamp > start_day_time + day_time, 'day has not passed'); + + self.day_index.write(self.day_index.read() + 1); + self.start_day_time.write(block_timestamp); + self.emit(NewDay { day_index: self.day_index.read() }); + } + fn get_user_pixels_placed(self: @ContractState, user: ContractAddress) -> u32 { let mut i = 0; let mut total = 0; @@ -435,19 +446,5 @@ pub mod ArtPeace { } } } - - #[generate_trait] - impl InternatImpl of InternalTrait { - fn increase_day_index(ref self: ContractState) { - let block_timestamp = starknet::get_block_timestamp(); - let start_day_time = self.start_day_time.read(); - - assert(block_timestamp > start_day_time + day_time, 'day has not passed'); - - self.day_index.write(self.day_index.read() + 1); - self.start_day_time.write(block_timestamp); - self.emit(NewDay { day_index: self.day_index.read() }); - } - } } diff --git a/onchain/src/interface.cairo b/onchain/src/interface.cairo index 5d1b785a..a26a1483 100644 --- a/onchain/src/interface.cairo +++ b/onchain/src/interface.cairo @@ -57,6 +57,9 @@ pub trait IArtPeace { fn claim_today_quest(ref self: TContractState, quest_id: u32); fn claim_main_quest(ref self: TContractState, quest_id: u32); + // Start a new day + fn increase_day_index(ref self: TContractState); + // Stats fn get_user_pixels_placed(self: @TContractState, user: starknet::ContractAddress) -> u32; fn get_user_pixels_placed_day( From 35080214025d5475ad2531c4a43639395c2e47dc Mon Sep 17 00:00:00 2001 From: TAdev0 Date: Thu, 11 Apr 2024 01:07:03 +0200 Subject: [PATCH 5/5] tests --- onchain/src/art_peace.cairo | 24 +++++------ onchain/src/interface.cairo | 6 +-- onchain/src/tests/art_peace.cairo | 66 ++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 34 deletions(-) diff --git a/onchain/src/art_peace.cairo b/onchain/src/art_peace.cairo index 1f276251..288604f8 100644 --- a/onchain/src/art_peace.cairo +++ b/onchain/src/art_peace.cairo @@ -79,7 +79,7 @@ pub mod ArtPeace { pub main_quests: Span, } - const day_time: u64 = consteval_int!(60 * 60 * 24); + const DAY_IN_SECONDS: u64 = consteval_int!(60 * 60 * 24); #[constructor] fn constructor(ref self: ContractState, init_params: InitParams) { @@ -257,6 +257,17 @@ pub mod ArtPeace { self.day_index.read() } + fn increase_day_index(ref self: ContractState) { + let block_timestamp = starknet::get_block_timestamp(); + let start_day_time = self.start_day_time.read(); + + assert(block_timestamp >= start_day_time + DAY_IN_SECONDS, 'day has not passed'); + + self.day_index.write(self.day_index.read() + 1); + self.start_day_time.write(block_timestamp); + self.emit(NewDay { day_index: self.day_index.read() }); + } + fn get_daily_quest_count(self: @ContractState) -> core::zeroable::NonZero:: { // TODO: hardcoded 3 daily quests 3 @@ -357,17 +368,6 @@ pub mod ArtPeace { } } - fn increase_day_index(ref self: ContractState) { - let block_timestamp = starknet::get_block_timestamp(); - let start_day_time = self.start_day_time.read(); - - assert(block_timestamp > start_day_time + day_time, 'day has not passed'); - - self.day_index.write(self.day_index.read() + 1); - self.start_day_time.write(block_timestamp); - self.emit(NewDay { day_index: self.day_index.read() }); - } - fn get_user_pixels_placed(self: @ContractState, user: ContractAddress) -> u32 { let mut i = 0; let mut total = 0; diff --git a/onchain/src/interface.cairo b/onchain/src/interface.cairo index a26a1483..9882ff36 100644 --- a/onchain/src/interface.cairo +++ b/onchain/src/interface.cairo @@ -40,6 +40,9 @@ pub trait IArtPeace { fn get_end_time(self: @TContractState) -> u64; fn get_day(self: @TContractState) -> u32; + // Start a new day + fn increase_day_index(ref self: TContractState); + // Get quest info fn get_daily_quest_count(self: @TContractState) -> core::zeroable::NonZero::; fn get_daily_quest( @@ -57,9 +60,6 @@ pub trait IArtPeace { fn claim_today_quest(ref self: TContractState, quest_id: u32); fn claim_main_quest(ref self: TContractState, quest_id: u32); - // Start a new day - fn increase_day_index(ref self: TContractState); - // Stats fn get_user_pixels_placed(self: @TContractState, user: starknet::ContractAddress) -> u32; fn get_user_pixels_placed_day( diff --git a/onchain/src/tests/art_peace.cairo b/onchain/src/tests/art_peace.cairo index ce0fa0a9..eff84e67 100644 --- a/onchain/src/tests/art_peace.cairo +++ b/onchain/src/tests/art_peace.cairo @@ -5,10 +5,14 @@ use art_peace::templates::{ ITemplateVerifierDispatcherTrait, TemplateMetadata }; +use core::poseidon::PoseidonTrait; +use core::hash::{HashStateTrait, HashStateExTrait}; + use snforge_std as snf; use snforge_std::{CheatTarget, ContractClassTrait}; use starknet::{ContractAddress, contract_address_const}; +const DAY_IN_SECONDS: u64 = consteval_int!(60 * 60 * 24); const WIDTH: u128 = 100; const HEIGHT: u128 = 100; const TIME_BETWEEN_PIXELS: u64 = 10; @@ -98,6 +102,21 @@ fn warp_to_next_available_time(art_peace: IArtPeaceDispatcher) { snf::start_warp(CheatTarget::One(art_peace.contract_address), last_time + TIME_BETWEEN_PIXELS); } +fn compute_template_hash(template: Span) -> felt252 { + let template_len = template.len(); + if template_len == 0 { + return 0; + } + + let mut hasher = PoseidonTrait::new(); + let mut i = 0; + while i < template_len { + hasher = hasher.update_with(*template.at(i)); + i += 1; + }; + hasher.finalize() +} + #[test] fn deploy_test() { let art_peace = IArtPeaceDispatcher { contract_address: deploy_contract() }; @@ -212,25 +231,6 @@ fn pixel_quest_test() { ); } -use core::poseidon::PoseidonTrait; -use core::hash::{HashStateTrait, HashStateExTrait}; - -// TODO: Move to src -fn compute_template_hash(template: Span) -> felt252 { - let template_len = template.len(); - if template_len == 0 { - return 0; - } - - let mut hasher = PoseidonTrait::new(); - let mut i = 0; - while i < template_len { - hasher = hasher.update_with(*template.at(i)); - i += 1; - }; - hasher.finalize() -} - #[test] fn template_full_basic_test() { let art_peace = IArtPeaceDispatcher { contract_address: deploy_contract() }; @@ -310,6 +310,34 @@ fn template_full_basic_test() { "Template is not completed after it should be" ); } + +#[test] +fn increase_day_test() { + let art_peace_address = deploy_contract(); + let art_peace = IArtPeaceDispatcher { contract_address: art_peace_address }; + + let current_day_index = art_peace.get_day(); + assert!(current_day_index == 0, "day index wrongly initialized"); + + snf::start_warp(CheatTarget::One(art_peace_address), DAY_IN_SECONDS); + art_peace.increase_day_index(); + let current_day_index = art_peace.get_day(); + assert!(current_day_index == 1, "day index not updated"); + snf::stop_warp(CheatTarget::One(art_peace_address)); +} + +#[test] +#[should_panic(expected: ('day has not passed',))] +fn increase_day_panic_test() { + let art_peace_address = deploy_contract(); + let art_peace = IArtPeaceDispatcher { contract_address: art_peace_address }; + + let current_day_index = art_peace.get_day(); + assert!(current_day_index == 0, "day index wrongly initialized"); + + snf::start_warp(CheatTarget::One(art_peace_address), DAY_IN_SECONDS - 1); + art_peace.increase_day_index(); +} // TODO: test invalid template inputs