Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refac: Fix Land ID logic #99

Merged
merged 16 commits into from
Oct 25, 2024
12 changes: 9 additions & 3 deletions land_registry/src/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ use starknet::ContractAddress;
#[derive(Drop, Copy, Serde, starknet::Store)]
pub struct Land {
owner: ContractAddress,
location: felt252,
location: Location,
area: u256,
land_use: LandUse,
is_approved: bool,
inspector: Option<ContractAddress>,
last_transaction_timestamp: u64,
}

#[derive(Debug, Drop, Copy, Clone, Serde, starknet::Store, PartialEq)]
#[derive(Drop, Copy, Serde, starknet::Store, PartialEq)]
pub struct Location {
latitude: felt252,
longitude: felt252,
}

#[derive(Debug, Drop, Copy, Serde, Clone, starknet::Store, PartialEq)]
pub enum LandUse {
Residential,
Commercial,
Expand All @@ -33,7 +39,7 @@ impl LandUseIntoFelt252 of Into<LandUse, felt252> {
#[starknet::interface]
pub trait ILandRegistry<TContractState> {
fn register_land(
ref self: TContractState, location: felt252, area: u256, land_use: LandUse,
ref self: TContractState, location: Location, area: u256, land_use: LandUse,
) -> u256;
fn transfer_land(ref self: TContractState, land_id: u256, new_owner: ContractAddress);
fn get_land(self: @TContractState, land_id: u256) -> Land;
Expand Down
11 changes: 6 additions & 5 deletions land_registry/src/land_register.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#[starknet::contract]
pub mod LandRegistryContract {
use starknet::{get_caller_address, get_block_timestamp, ContractAddress};
use land_registry::interface::{ILandRegistry, Land, LandUse};
use land_registry::interface::{ILandRegistry, Land, LandUse, Location};
use land_registry::land_nft::{ILandNFTDispatcher, ILandNFTDispatcherTrait, LandNFT};
use land_registry::utils::{create_land_id};
use core::array::ArrayTrait;
use starknet::storage::{Map, StorageMapWriteAccess, StorageMapReadAccess};

Expand Down Expand Up @@ -31,7 +32,7 @@ pub mod LandRegistryContract {
struct LandRegistered {
land_id: u256,
owner: ContractAddress,
location: felt252,
location: Location,
area: u256,
land_use: felt252,
}
Expand Down Expand Up @@ -63,11 +64,11 @@ pub mod LandRegistryContract {
#[abi(embed_v0)]
impl LandRegistry of ILandRegistry<ContractState> {
fn register_land(
ref self: ContractState, location: felt252, area: u256, land_use: LandUse,
ref self: ContractState, location: Location, area: u256, land_use: LandUse,
) -> u256 {
let caller = get_caller_address();
let timestamp = get_block_timestamp();
let land_id = self.land_count.read() + 1;
let land_id = create_land_id(caller, timestamp, location);

let new_land = Land {
owner: caller,
Expand All @@ -80,7 +81,7 @@ pub mod LandRegistryContract {
};

self.lands.write(land_id, new_land);
self.land_count.write(land_id);
self.land_count.write(self.land_count.read() + 1);

let owner_land_count = self.owner_land_count.read(caller);
self.owner_lands.write((caller, owner_land_count), land_id);
Expand Down
14 changes: 14 additions & 0 deletions land_registry/src/utils.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
//helper functions
use starknet::{get_caller_address, get_block_timestamp, ContractAddress};
use core::poseidon::PoseidonTrait;
use core::hash::{HashStateTrait, HashStateExTrait};
use land_registry::interface::Location;

//LandHelpers

pub fn create_land_id(caller: ContractAddress, timestamp: u64, location: Location) -> 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)
.finalize();

let felt_land_id = caller_hash + timestamp_hash + location_hash;
let land_id: u256 = felt_land_id.into();
land_id
}
66 changes: 60 additions & 6 deletions land_registry/tests/test_land_register.cairo
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address};
use snforge_std::{
declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address,
stop_cheat_caller_address, start_cheat_block_timestamp, stop_cheat_block_timestamp
};
use starknet::ContractAddress;

use land_registry::interface::{ILandRegistryDispatcher, ILandRegistryDispatcherTrait};


use land_registry::interface::LandUse;
use land_registry::interface::{LandUse, Location};

pub mod Accounts {
use starknet::ContractAddress;
Expand Down Expand Up @@ -44,7 +44,7 @@ fn test_can_register_land() {

// Set up test data
let caller_address = starknet::contract_address_const::<0x123>();
let location: felt252 = 'Test Location';
let location: Location = Location { latitude: 1, longitude: 2 };
let area: u256 = 1000;
let land_use = LandUse::Residential;

Expand All @@ -66,3 +66,57 @@ fn test_can_register_land() {
assert(registered_land.inspector.is_none(), 'Should have no inspector');
}

#[test]
fn test_can_create_land_id() {
let contract_address = deploy("LandRegistryContract");

// Get an instance of the deployed Counter contract
let land_register_dispatcher = ILandRegistryDispatcher { contract_address };

// Set up test data
let area: u256 = 1000;
let land_use = LandUse::Residential;

let location1: Location = Location { latitude: 1, longitude: 2 };
let location2: Location = Location { latitude: 3, longitude: 4 };
let location3: Location = Location { latitude: 5, longitude: 6 };

//Testcase 1
start_cheat_caller_address(contract_address, 123.try_into().unwrap());
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)'
);

stop_cheat_caller_address(contract_address);
stop_cheat_block_timestamp(contract_address);

//Testcase 2
start_cheat_caller_address(contract_address, 456.try_into().unwrap());
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)'
);

stop_cheat_caller_address(contract_address);
stop_cheat_block_timestamp(contract_address);

//Testcase 3
start_cheat_caller_address(contract_address, 789.try_into().unwrap());
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)'
);

stop_cheat_caller_address(contract_address);
stop_cheat_block_timestamp(contract_address);
}
Loading