From 2b86a90300806ae7bea43afe3142257fa8fbd7d0 Mon Sep 17 00:00:00 2001 From: Birdmannn Date: Fri, 20 Dec 2024 22:43:41 +0100 Subject: [PATCH] fix: Update land id logic. --- land_registry/src/land_register.cairo | 17 +++++++++++++++-- land_registry/src/utils.cairo | 9 +++++++-- land_registry/tests/test_land_register.cairo | 19 ++++++------------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/land_registry/src/land_register.cairo b/land_registry/src/land_register.cairo index 57d80bd5..19edf5c4 100644 --- a/land_registry/src/land_register.cairo +++ b/land_registry/src/land_register.cairo @@ -68,6 +68,7 @@ pub mod LandRegistryContract { price_update_count: Map::, // listing_id -> number of price updates active_listings: Map::, // index -> listing_id active_listing_count: u256, + id_exists: Map::, } #[event] @@ -130,9 +131,21 @@ pub mod LandRegistryContract { let caller = get_caller_address(); let timestamp = get_block_timestamp(); - // Generate unique land ID based on owner, timestamp and location - let land_id = create_land_id(caller, timestamp, location); + // Generate unique land ID based on owner, timestamp, location, and a counter + // This counter increases for each registration to re-ensure uniqueness. + let mut counter = self.land_count.read(); + let mut land_id = create_land_id(caller, timestamp, location, counter); + + while self.id_exists.read(land_id) { + // This is highly impossible, but not impossible. re-iterate. + counter += 1; + land_id = create_land_id(caller, timestamp, location, counter); + }; + let transaction_count = self.land_transaction_count.read(land_id); + + // id is available, now make it unavailable. + self.id_exists.write(land_id, true); // Create new land record let new_land = Land { diff --git a/land_registry/src/utils.cairo b/land_registry/src/utils.cairo index 6470df15..b20c9f63 100644 --- a/land_registry/src/utils.cairo +++ b/land_registry/src/utils.cairo @@ -4,16 +4,21 @@ pub mod utils { use core::hash::{HashStateTrait, HashStateExTrait}; use land_registry::interface::land_register::{Location, LandUse}; + pub const MODULO_BASE: u256 = 100000000000000000000000000000000; // reduce the id to 32 digits - pub fn create_land_id(caller: ContractAddress, timestamp: u64, location: Location) -> u256 { + pub fn create_land_id( + caller: ContractAddress, timestamp: u64, location: Location, counter: u256 + ) -> u256 { let caller_hash = PoseidonTrait::new().update_with(caller).finalize(); let timestamp_hash = PoseidonTrait::new().update_with(timestamp).finalize(); let location_hash = PoseidonTrait::new() .update_with(location.latitude + location.longitude) + .update_with(counter * 255_u256) .finalize(); let felt_land_id = caller_hash + timestamp_hash + location_hash; - let land_id: u256 = felt_land_id.into(); + let mut land_id: u256 = felt_land_id.into(); + land_id = land_id % MODULO_BASE; land_id } diff --git a/land_registry/tests/test_land_register.cairo b/land_registry/tests/test_land_register.cairo index 64977010..7db74af9 100644 --- a/land_registry/tests/test_land_register.cairo +++ b/land_registry/tests/test_land_register.cairo @@ -7,6 +7,7 @@ use land_registry::interface::land_register::{ ILandRegistryDispatcher, ILandRegistryDispatcherTrait, LandUse, Location, LandStatus, ListingStatus }; +use land_registry::utils::utils::MODULO_BASE; use starknet::ContractAddress; use core::array::ArrayTrait; use core::traits::TryInto; @@ -54,6 +55,7 @@ fn test_can_register_land() { // Register the land let land_id = land_register_dispatcher.register_land(location, area, land_use); + assert_le!(land_id, MODULO_BASE - 1); // ensure the id is within the 32-digit range. // Get the registered land let registered_land = land_register_dispatcher.get_land(land_id); @@ -89,10 +91,7 @@ fn test_can_create_land_id() { start_cheat_block_timestamp(contract_address, 10); let id_1 = land_register_dispatcher.register_land(location1, area, land_use); - assert( - id_1 == 689216240506425664519995665376830138699152617179386928383439581252423035401, - 'land_id is not as expected (1)' - ); + assert(id_1 == 76145004285422410213294800731643, 'land_id is not as expected (1)'); stop_cheat_caller_address(contract_address); stop_cheat_block_timestamp(contract_address); @@ -102,10 +101,7 @@ fn test_can_create_land_id() { start_cheat_block_timestamp(contract_address, 20); let id_2 = land_register_dispatcher.register_land(location2, area, land_use); - assert( - id_2 == 14747943344839073547474207539210781044163306897453701102442319167742800565, - 'land_id is not as expected (2)' - ); + assert(id_2 == 4946593347159045342371278487724, 'land_id is not as expected (2)'); stop_cheat_caller_address(contract_address); stop_cheat_block_timestamp(contract_address); @@ -115,11 +111,8 @@ fn test_can_create_land_id() { start_cheat_block_timestamp(contract_address, 30); let id_3 = land_register_dispatcher.register_land(location3, area, land_use); - assert( - id_3 == 864555402638950626684962868225518693284860492943333490893906025290030385222, - 'land_id is not as expected (3)' - ); - + assert(id_3 == 83119874197453254617171158536104, 'land_id is not as expected (3)'); + println!("id 3: {}", id_3); stop_cheat_caller_address(contract_address); stop_cheat_block_timestamp(contract_address); }