diff --git a/CHANGELOG.md b/CHANGELOG.md index 30c5ddfec..29af7bf5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ref: Rename Set Amount Splitter to Fixed Amount Splitter [(#754)](https://github.com/andromedaprotocol/andromeda-core/pull/754) - Point ADO: remove Rates module from the contract[(#761)](https://github.com/andromedaprotocol/andromeda-core/pull/761) - feat: SignedDecimal for Distance [(#774)](https://github.com/andromedaprotocol/andromeda-core/pull/774) +- feat: SignedDecimal for Point [(#779)](https://github.com/andromedaprotocol/andromeda-core/pull/779) - feat: SignedDecimal for Graph [(#778)](https://github.com/andromedaprotocol/andromeda-core/pull/778) ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 06ab0c380..2d56c87ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -770,7 +770,7 @@ dependencies = [ [[package]] name = "andromeda-point" -version = "0.1.0" +version = "0.1.0-a.1" dependencies = [ "andromeda-math", "andromeda-std", diff --git a/contracts/math/andromeda-graph/src/contract.rs b/contracts/math/andromeda-graph/src/contract.rs index 2fc3322c4..a95a3a308 100644 --- a/contracts/math/andromeda-graph/src/contract.rs +++ b/contracts/math/andromeda-graph/src/contract.rs @@ -376,8 +376,6 @@ pub fn execute_store_user_coordinate( let user: AndrAddr = user_res.owner; let user_addr = user.get_raw_address(&ctx.deps.as_ref())?; - user_point_coordinate.validate()?; - USER_COORDINATE.save(ctx.deps.storage, user_addr, &user_point_coordinate)?; } else { return Err(ContractError::InvalidADOType { @@ -487,9 +485,9 @@ pub fn get_user_coordinate(deps: Deps, user: AndrAddr) -> Result { let msg_response = PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: Some("10".to_string()), + x_coordinate: SignedDecimal::from_ratio(10, 1), + y_coordinate: SignedDecimal::from_ratio(10, 1), + z_coordinate: Some(SignedDecimal::from_ratio(10, 1)), }; SystemResult::Ok(ContractResult::Ok(to_json_binary(&msg_response).unwrap())) } diff --git a/contracts/math/andromeda-point/Cargo.toml b/contracts/math/andromeda-point/Cargo.toml index 286c84d11..73d1744f8 100644 --- a/contracts/math/andromeda-point/Cargo.toml +++ b/contracts/math/andromeda-point/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-point" -version = "0.1.0" +version = "0.1.0-a.1" authors = ["Mitar Djakovic "] edition = "2021" rust-version = "1.75.0" diff --git a/contracts/math/andromeda-point/src/execute.rs b/contracts/math/andromeda-point/src/execute.rs index d26400e88..0e067fae1 100644 --- a/contracts/math/andromeda-point/src/execute.rs +++ b/contracts/math/andromeda-point/src/execute.rs @@ -57,8 +57,6 @@ pub fn set_point(ctx: ExecuteContext, point: PointCoordinate) -> Result, +#[test] +fn test_set_and_query_point_with_decimals() { + let (mut deps, info) = proper_initialization(PointRestriction::Private); + + // Set a point with decimal coordinates + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(12345, 1000), // 12.345 + y_coordinate: SignedDecimal::from_ratio(-6789, 1000), // -6.789 + z_coordinate: Some(SignedDecimal::from_ratio(31415, 10000)), // 3.1415 + }; + + set_point(deps.as_mut(), &point, info.sender.as_ref()).unwrap(); + + let query_res: PointCoordinate = query_point(deps.as_ref()).unwrap(); + + // Assert that the set point matches the queried point + assert_eq!(point, query_res); } #[test] -fn test_set_point_invalid() { - let test_cases = vec![ - TestHandlePointCoordinate { - name: "Invalid x_coordinate", - point_coordinate: PointCoordinate { - x_coordinate: "10.abc".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: Some("10".to_string()), - }, - expected_error: Some(ContractError::ParsingError { - err: "x_coordinate: can not parse to f64".to_string(), - }), - }, - TestHandlePointCoordinate { - name: "Invalid y_coordinate", - point_coordinate: PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10.abc".to_string(), - z_coordinate: None, - }, - expected_error: Some(ContractError::ParsingError { - err: "y_coordinate: can not parse to f64".to_string(), - }), - }, - TestHandlePointCoordinate { - name: "Invalid z_coordinate", - point_coordinate: PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: Some("10.abc".to_string()), - }, - expected_error: Some(ContractError::ParsingError { - err: "z_coordinate: can not parse to f64".to_string(), - }), - }, - ]; - - for test in test_cases { - let res = test.point_coordinate.validate(); - - if let Some(err) = test.expected_error { - assert_eq!(res.unwrap_err(), err, "{}", test.name); - continue; - } +fn test_update_point_with_decimals() { + let (mut deps, info) = proper_initialization(PointRestriction::Private); + + // Initial point + let initial_point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(1, 1), // 1.0 + y_coordinate: SignedDecimal::from_ratio(1, 1), // 1.0 + z_coordinate: Some(SignedDecimal::from_ratio(1, 1)), // 1.0 + }; + + set_point(deps.as_mut(), &initial_point, info.sender.as_ref()).unwrap(); - assert!(res.is_ok()) - } + // Update to a new point with decimals + let updated_point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(-123456, 10000), // -12.3456 + y_coordinate: SignedDecimal::from_ratio(78901, 10000), // 7.8901 + z_coordinate: Some(SignedDecimal::from_ratio(22222, 1000)), // 22.222 + }; + + set_point(deps.as_mut(), &updated_point, info.sender.as_ref()).unwrap(); + + let query_res: PointCoordinate = query_point(deps.as_ref()).unwrap(); + + // Assert that the updated point matches the queried point + assert_eq!(updated_point, query_res); } #[test] fn test_delete_point() { let (mut deps, info) = proper_initialization(PointRestriction::Private); - let point = PointCoordinate::from_f64(10_f64, 10_f64, Some(10_f64)); + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(10, 1), + y_coordinate: SignedDecimal::from_ratio(10, 1), + z_coordinate: Some(SignedDecimal::from_ratio(10, 1)), + }; + set_point(deps.as_mut(), &point, info.sender.as_ref()).unwrap(); delete_point(deps.as_mut(), info.sender.as_ref()).unwrap(); query_point(deps.as_ref()).unwrap_err(); @@ -100,7 +104,11 @@ fn test_delete_point() { fn test_restriction_private() { let (mut deps, info) = proper_initialization(PointRestriction::Private); - let point = PointCoordinate::from_f64(10_f64, 10_f64, Some(10_f64)); + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(10, 1), + y_coordinate: SignedDecimal::from_ratio(10, 1), + z_coordinate: Some(SignedDecimal::from_ratio(10, 1)), + }; let external_user = "external".to_string(); // Set Point as owner @@ -125,7 +133,11 @@ fn test_restriction_private() { fn test_restriction_public() { let (mut deps, info) = proper_initialization(PointRestriction::Public); - let point = PointCoordinate::from_f64(10_f64, 10_f64, Some(10_f64)); + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(10, 1), + y_coordinate: SignedDecimal::from_ratio(10, 1), + z_coordinate: Some(SignedDecimal::from_ratio(10, 1)), + }; let external_user = "external".to_string(); // Set Point as owner @@ -152,8 +164,16 @@ fn test_restriction_public() { fn test_restriction_restricted() { let (mut deps, info) = proper_initialization(PointRestriction::Restricted); - let point = PointCoordinate::from_f64(10_f64, 10_f64, Some(10_f64)); - let point2 = PointCoordinate::from_f64(5_f64, 5_f64, Some(5_f64)); + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(10, 1), + y_coordinate: SignedDecimal::from_ratio(10, 1), + z_coordinate: Some(SignedDecimal::from_ratio(10, 1)), + }; + let point2 = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(5, 1), + y_coordinate: SignedDecimal::from_ratio(5, 1), + z_coordinate: Some(SignedDecimal::from_ratio(5, 1)), + }; let external_user = "external".to_string(); let external_user2 = "external2".to_string(); @@ -193,12 +213,59 @@ fn test_restriction_restricted() { query_point(deps.as_ref()).unwrap(); } +#[test] +fn test_restriction_private_with_decimals() { + let (mut deps, info) = proper_initialization(PointRestriction::Private); + + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(50505, 10000), // 5.0505 + y_coordinate: SignedDecimal::from_ratio(-30303, 10000), // -3.0303 + z_coordinate: Some(SignedDecimal::from_ratio(10101, 10000)), // 1.0101 + }; + let external_user = "external".to_string(); + + // Set point as owner + set_point(deps.as_mut(), &point, info.sender.as_ref()).unwrap(); + + // Attempt to delete the point as an external user (should fail) + delete_point(deps.as_mut(), &external_user).unwrap_err(); + + // Ensure the point is still present + let query_res: PointCoordinate = query_point(deps.as_ref()).unwrap(); + assert_eq!(point, query_res); +} + +#[test] +fn test_restriction_public_with_decimals() { + let (mut deps, _) = proper_initialization(PointRestriction::Public); + + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(98765, 10000), // 9.8765 + y_coordinate: SignedDecimal::from_ratio(4321, 10000), // 0.4321 + z_coordinate: Some(SignedDecimal::from_ratio(-12345, 10000)), // -1.2345 + }; + let external_user = "external".to_string(); + + // Set point as external user + set_point(deps.as_mut(), &point, &external_user).unwrap(); + + // Delete the point as external user + delete_point(deps.as_mut(), &external_user).unwrap(); + + // Ensure the point is deleted + query_point(deps.as_ref()).unwrap_err(); +} + #[test] fn test_query_data_owner() { let (mut deps, _) = proper_initialization(PointRestriction::Restricted); let external_user = "external".to_string(); let external_user2 = "external2".to_string(); - let point = PointCoordinate::from_f64(10_f64, 10_f64, Some(10_f64)); + let point = PointCoordinate { + x_coordinate: SignedDecimal::from_ratio(10, 1), + y_coordinate: SignedDecimal::from_ratio(10, 1), + z_coordinate: Some(SignedDecimal::from_ratio(10, 1)), + }; set_point(deps.as_mut(), &point, &external_user.clone()).unwrap(); let res: GetDataOwnerResponse = diff --git a/packages/andromeda-math/src/point.rs b/packages/andromeda-math/src/point.rs index a1bf68d32..ad8525d32 100644 --- a/packages/andromeda-math/src/point.rs +++ b/packages/andromeda-math/src/point.rs @@ -1,5 +1,6 @@ -use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query, error::ContractError}; +use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::SignedDecimal; #[andr_instantiate] #[cw_serde] @@ -24,49 +25,9 @@ pub enum PointRestriction { #[cw_serde] pub struct PointCoordinate { - pub x_coordinate: String, - pub y_coordinate: String, - pub z_coordinate: Option, -} - -impl PointCoordinate { - pub fn from_f64(x_coordinate: f64, y_coordinate: f64, z_coordinate: Option) -> Self { - let z_coordinate: Option = z_coordinate.map(|z| z.to_string()); - - Self { - x_coordinate: x_coordinate.to_string(), - y_coordinate: y_coordinate.to_string(), - z_coordinate, - } - } - pub fn validate(&self) -> Result<(), ContractError> { - let x_coordinate = self.x_coordinate.parse::(); - if x_coordinate.is_err() { - return Err(ContractError::ParsingError { - err: "x_coordinate: can not parse to f64".to_string(), - }); - } - - let y_coordinate = self.y_coordinate.parse::(); - if y_coordinate.is_err() { - return Err(ContractError::ParsingError { - err: "y_coordinate: can not parse to f64".to_string(), - }); - } - - match &self.z_coordinate { - None => (), - Some(z) => { - let z_coordinate = z.parse::(); - if z_coordinate.is_err() { - return Err(ContractError::ParsingError { - err: "z_coordinate: can not parse to f64".to_string(), - }); - } - } - } - Ok(()) - } + pub x_coordinate: SignedDecimal, + pub y_coordinate: SignedDecimal, + pub z_coordinate: Option, } #[andr_query] @@ -83,69 +44,3 @@ pub enum QueryMsg { pub struct GetDataOwnerResponse { pub owner: AndrAddr, } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_validate_point_coordinate_valid() { - let point = PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: Some("10".to_string()), - }; - let res = point.validate(); - assert!(res.is_ok()); - - let point = PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: None, - }; - let res = point.validate(); - assert!(res.is_ok()); - } - - #[test] - fn test_validate_point_coordinate_invalid() { - let point = PointCoordinate { - x_coordinate: "10.abc".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: Some("10".to_string()), - }; - let res = point.validate().unwrap_err(); - assert_eq!( - res, - ContractError::ParsingError { - err: "x_coordinate: can not parse to f64".to_string() - } - ); - - let point = PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10.abc".to_string(), - z_coordinate: Some("10".to_string()), - }; - let res = point.validate().unwrap_err(); - assert_eq!( - res, - ContractError::ParsingError { - err: "y_coordinate: can not parse to f64".to_string() - } - ); - - let point = PointCoordinate { - x_coordinate: "10".to_string(), - y_coordinate: "10".to_string(), - z_coordinate: Some("10.xyz".to_string()), - }; - let res = point.validate().unwrap_err(); - assert_eq!( - res, - ContractError::ParsingError { - err: "z_coordinate: can not parse to f64".to_string() - } - ); - } -}