Skip to content

Commit

Permalink
Distance ADO (#570)
Browse files Browse the repository at this point in the history
Co-authored-by: Connor Barr <[email protected]>
  • Loading branch information
mdjakovic0920 and crnbarr93 authored Dec 6, 2024
1 parent d437608 commit a146675
Show file tree
Hide file tree
Showing 13 changed files with 553 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added Distance ADO [(#570)](https://github.com/andromedaprotocol/andromeda-core/pull/570)

### Changed

### Fixed
Expand All @@ -28,7 +30,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added Restake and Redelegate to Validator Staking [(#622)](https://github.com/andromedaprotocol/andromeda-core/pull/622)
- Added andromeda-math and andromeda-account packages[(#672)](https://github.com/andromedaprotocol/andromeda-core/pull/672)


### Changed

- Removed staking from vesting contract [(#554)](https://github.com/andromedaprotocol/andromeda-core/pull/554)
Expand Down
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions contracts/modules/andromeda-distance/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[alias]
wasm = "build --release --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --example schema"
32 changes: 32 additions & 0 deletions contracts/modules/andromeda-distance/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "andromeda-distance"
version = "0.1.0-beta.1"
edition = "2021"
rust-version = "1.75.0"

[lib]
crate-type = ["cdylib", "rlib"]

[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
testing = ["cw-multi-test", "andromeda-testing"]


[dependencies]
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw-storage-plus = { workspace = true }
cw-utils = { workspace = true }

andromeda-std = { workspace = true }
andromeda-math = { workspace = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
cw-multi-test = { workspace = true, optional = true }
andromeda-testing = { workspace = true, optional = true }

[dev-dependencies]
andromeda-app = { workspace = true }
10 changes: 10 additions & 0 deletions contracts/modules/andromeda-distance/examples/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use andromeda_math::distance::{ExecuteMsg, InstantiateMsg, QueryMsg};
use cosmwasm_schema::write_api;
fn main() {
write_api! {
instantiate: InstantiateMsg,
query: QueryMsg,
execute: ExecuteMsg,

}
}
167 changes: 167 additions & 0 deletions contracts/modules/andromeda-distance/src/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response};

use andromeda_math::distance::{Coordinate, DistanceType, ExecuteMsg, InstantiateMsg, QueryMsg};
use andromeda_std::{
ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg},
ado_contract::ADOContract,
common::{actions::call_action, context::ExecuteContext, encode_binary},
error::ContractError,
};

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:andromeda-distance";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
let resp = ADOContract::default().instantiate(
deps.storage,
env,
deps.api,
&deps.querier,
info,
BaseInstantiateMsg {
ado_type: CONTRACT_NAME.to_string(),
ado_version: CONTRACT_VERSION.to_string(),
kernel_address: msg.kernel_address,
owner: msg.owner,
},
)?;

Ok(resp)
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
let ctx = ExecuteContext::new(deps, info, env);
match msg {
ExecuteMsg::AMPReceive(pkt) => {
ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute)
}
_ => handle_execute(ctx, msg),
}
}

#[allow(clippy::match_single_binding)]
fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result<Response, ContractError> {
let action_response = call_action(
&mut ctx.deps,
&ctx.info,
&ctx.env,
&ctx.amp_ctx,
msg.as_ref(),
)?;

let res = match msg {
_ => ADOContract::default().execute(ctx, msg),
}?;

Ok(res
.add_submessages(action_response.messages)
.add_attributes(action_response.attributes)
.add_events(action_response.events))
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary, ContractError> {
match msg {
QueryMsg::GetDistanceBetween2Points {
point_1,
point_2,
decimal,
} => encode_binary(&get_distance(point_1, point_2, decimal)?),
QueryMsg::GetManhattanDistance {
point_1,
point_2,
decimal,
} => encode_binary(&get_manhattan_distance(point_1, point_2, decimal)?),
_ => ADOContract::default().query(deps, env, msg),
}
}

fn get_distance(
point_1: Coordinate,
point_2: Coordinate,
decimal: u16,
) -> Result<String, ContractError> {
decimal_validate(decimal)?;

let distance = calculate_distance(point_1, point_2, decimal, DistanceType::Straight)?;

Ok(distance)
}

fn get_manhattan_distance(
point_1: Coordinate,
point_2: Coordinate,
decimal: u16,
) -> Result<String, ContractError> {
decimal_validate(decimal)?;

let manhattan_distance =
calculate_distance(point_1, point_2, decimal, DistanceType::Manhattan)?;

Ok(manhattan_distance)
}

fn calculate_distance(
point_1: Coordinate,
point_2: Coordinate,
decimal: u16,
distance_type: DistanceType,
) -> Result<String, ContractError> {
let delta_x = (point_1.x_coordinate - point_2.x_coordinate).abs();
let delta_y = (point_1.y_coordinate - point_2.y_coordinate).abs();
let z_1 = point_1.z_coordinate.unwrap_or(0_f64);
let z_2 = point_2.z_coordinate.unwrap_or(0_f64);
let delta_z = (z_1 - z_2).abs();

match distance_type {
DistanceType::Straight => {
let distance = (delta_x.powf(2_f64) + delta_y.powf(2_f64) + delta_z.powf(2_f64)).sqrt();
let distance_decimal = format!("{:.*}", decimal as usize, distance)
.parse::<f64>()
.map_err(|_| ContractError::ParsingError {
err: "Parsing error".to_string(),
})?;

Ok(distance_decimal.to_string())
}
DistanceType::Manhattan => {
let manhattan_distance = delta_x + delta_y + delta_z;
let manhattan_distance_decimal = format!("{:.*}", decimal as usize, manhattan_distance)
.parse::<f64>()
.map_err(|_| ContractError::ParsingError {
err: "Parsing error".to_string(),
})?;

Ok(manhattan_distance_decimal.to_string())
}
}
}

fn decimal_validate(decimal: u16) -> Result<(), ContractError> {
if decimal > 18 {
return Err(ContractError::InvalidParameter {
error: Some("Decimal value too large".to_string()),
});
}
Ok(())
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION)
}
6 changes: 6 additions & 0 deletions contracts/modules/andromeda-distance/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod contract;
#[cfg(test)]
pub mod testing;

#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))]
pub mod mock;
83 changes: 83 additions & 0 deletions contracts/modules/andromeda-distance/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))]
use crate::contract::{execute, instantiate, query};
use andromeda_modules::distance::{Coordinate, InstantiateMsg, QueryMsg};
use andromeda_testing::mock::MockApp;
use andromeda_testing::{
mock_ado,
mock_contract::{ExecuteResult, MockADO, MockContract},
};
use cosmwasm_std::{Addr, Empty};
use cw_multi_test::{Contract, ContractWrapper, Executor};

pub struct MockDistance(Addr);
mock_ado!(MockDistance, ExecuteMsg, QueryMsg);

impl MockDistance {
pub fn instantiate(
code_id: u64,
sender: Addr,
app: &mut MockApp,
kernel_address: String,
owner: Option<String>,
) -> MockDistance {
let msg = mock_distance_instantiate_msg(kernel_address, owner);
let addr = app
.instantiate_contract(
code_id,
sender.clone(),
&msg,
&[],
"Distance Contract",
Some(sender.to_string()),
)
.unwrap();
MockDistance(Addr::unchecked(addr))
}

pub fn query_distance(
&self,
app: &mut MockApp,
point_1: Coordinate,
point_2: Coordinate,
decimal: u16,
) -> String {
let msg = QueryMsg::GetDistanceBetween2Points {
point_1,
point_2,
decimal,
};
let res: String = self.query(app, msg);
res
}

pub fn query_manhattan_distance(
&self,
app: &mut MockApp,
point_1: Coordinate,
point_2: Coordinate,
decimal: u16,
) -> String {
let msg = QueryMsg::GetManhattanDistance {
point_1,
point_2,
decimal,
};
let res: String = self.query(app, msg);
res
}
}

pub fn mock_andromeda_distance() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new_with_empty(execute, instantiate, query);
Box::new(contract)
}

pub fn mock_distance_instantiate_msg(
kernel_address: String,
owner: Option<String>,
) -> InstantiateMsg {
InstantiateMsg {
kernel_address,
owner,
}
}
Loading

0 comments on commit a146675

Please sign in to comment.