Skip to content

Commit

Permalink
using custom tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
dzmitry-lahoda committed Mar 15, 2024
1 parent 3a6b1aa commit c3bc234
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 42 deletions.
1 change: 0 additions & 1 deletion contracts/cosmwasm/order/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/// each pair waits at least this amount of blocks before being decided
pub const BATCH_EPOCH: u32 = 2;

Expand Down
13 changes: 8 additions & 5 deletions contracts/cosmwasm/order/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ pub mod order {
.add_attribute("order_id", tracking.order_id.to_string())
.add_attribute("amount_taken", tracking.amount_taken.to_string())
.add_attribute("promised", tracking.promised.to_string())
.add_attribute("meta", "solution is not verified, do not use for big funds".to_string())
.add_attribute(
"meta",
"solution is not verified, do not use for big funds".to_string(),
)
}
}

Expand All @@ -70,8 +73,8 @@ pub mod solution {
) -> Event {
let solution_id = crate::types::solution_id(&(owner.to_string(), ab.clone(), block_added));
let solution_chosen = Event::new("mantis-solution-chosen")
.add_attribute("token_a", ab.clone().0)
.add_attribute("token_b", ab.clone().1)
.add_attribute("token_a", ab.clone().a)
.add_attribute("token_b", ab.clone().b)
.add_attribute("solver_address", ctx.info.sender.to_string())
.add_attribute("cow_volume", cow_volume.to_string())
.add_attribute("cross_chain_volume", cow_volume.to_string())
Expand All @@ -83,8 +86,8 @@ pub mod solution {

pub fn mantis_solution_upserted(ab: &DenomPair, ctx: &ExecCtx<'_>) -> Event {
let solution_upserted = Event::new("mantis-solution-upserted")
.add_attribute("token_a", ab.clone().0)
.add_attribute("token_b", ab.clone().1)
.add_attribute("token_a", ab.clone().a)
.add_attribute("token_b", ab.clone().b)
.add_attribute("solver_address", ctx.info.sender.to_string());
solution_upserted
}
Expand Down
30 changes: 12 additions & 18 deletions contracts/cosmwasm/order/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,23 @@ impl OrderContract<'_> {

let a_funds = cvm_filled
.iter()
.filter(|x| x.tracking.amount_taken.denom == msg.pair.0)
.filter(|x| x.tracking.amount_taken.denom == msg.pair.a)
.map(|x| x.tracking.amount_taken.amount)
.sum();

let b_funds = cvm_filled
.iter()
.filter(|x| x.tracking.amount_taken.denom == msg.pair.1)
.filter(|x| x.tracking.amount_taken.denom == msg.pair.b)
.map(|x| x.tracking.amount_taken.amount)
.sum();

let funds = vec![
Coin {
denom: msg.pair.0,
denom: msg.pair.a,
amount: a_funds,
},
Coin {
denom: msg.pair.1,
denom: msg.pair.b,
amount: b_funds,
},
];
Expand All @@ -242,11 +242,10 @@ impl OrderContract<'_> {
let at_least_one = all_orders.first().expect("at least one");

// normalize pair
let mut ab = (
let mut ab = DenomPair::new(
at_least_one.given().denom.clone(),
at_least_one.wants().denom.clone(),
);
ab.sort_selection();

// add solution to total solutions
let possible_solution = SolutionItem {
Expand All @@ -258,11 +257,7 @@ impl OrderContract<'_> {

self.start_solution(ctx.branch(), ab.clone())?;

let solution_key = (
ab.clone().0,
ab.clone().1,
ctx.info.sender.clone().to_string(),
);
let solution_key = (ab.clone(), ctx.info.sender.clone().to_string());

self.solutions
.save(ctx.deps.storage, &solution_key, &possible_solution)?;
Expand All @@ -276,7 +271,7 @@ impl OrderContract<'_> {
// get all solution for pair
let all_solutions: Result<Vec<SolutionItem>, _> = self
.solutions
.prefix(ab.clone())
.prefix(ab.clone().into())
.range(ctx.deps.storage, None, None, Order::Ascending)
.map(|r| r.map(|(_, solution)| solution))
.collect();
Expand All @@ -300,20 +295,19 @@ impl OrderContract<'_> {
// pick up optimal solution with solves with bank
let mut a_in = 0u128;
let mut b_in = 0u128;
let (a, b) = ab.clone();
let mut transfers = vec![];
let mut solution_item: SolutionItem = possible_solution;
let mut volume = 0u128;
for solution in all_solutions {
let solution_orders = join_solution_with_orders(&self.orders, &solution.msg, &ctx)?;
let a_total_from_orders_in_solution: u128 = solution_orders
.iter()
.filter(|x| x.given().denom == a)
.filter(|x| x.given().denom == ab.a)
.map(|x: &SolvedOrder| x.given().amount.u128())
.sum();
let b_total_from_orders_in_solution: u128 = solution_orders
.iter()
.filter(|x: &&SolvedOrder| x.given().denom == b)
.filter(|x: &&SolvedOrder| x.given().denom == ab.b)
.map(|x| x.given().amount.u128())
.sum();

Expand Down Expand Up @@ -359,13 +353,13 @@ impl OrderContract<'_> {

let cross_chain_b: u128 = all_orders
.iter()
.filter(|x| x.given().denom != ab.0)
.filter(|x| x.given().denom != ab.a)
.map(|x| x.given_cross_chain().u128())
.sum();

let cross_chain_a: u128 = all_orders
.iter()
.filter(|x| x.given().denom != ab.1)
.filter(|x| x.given().denom != ab.b)
.map(|x| x.given_cross_chain().u128())
.sum();

Expand Down Expand Up @@ -555,7 +549,7 @@ impl OrderContract<'_> {
}

fn emit_solution_chosen(
ab: (String, String),
ab: DenomPair,
ctx: ExecCtx<'_>,
transfers: &Vec<CowFillResult>,
volume: u128,
Expand Down
65 changes: 62 additions & 3 deletions contracts/cosmwasm/order/src/ordered_tuple.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,71 @@
use std::vec;

use cosmwasm_schema::cw_serde;
use cosmwasm_std::{StdError, StdResult};
use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey};
pub use tuples::*;

#[cw_serde]
#[derive(Eq)]
pub struct OrderedTuple2<T> {
// rust does not allows 'r#1'
pub a: T,
pub b: T,
}

impl<'a, T: Clone + Prefixer<'a> + KeyDeserialize + PrimaryKey<'a>> PrimaryKey<'a>
for OrderedTuple2<T>
{
type Prefix = T;

type SubPrefix = T;

type Suffix = ();

type SuperSuffix = (T, T);
fn key(&self) -> Vec<Key> {
let mut keys = self.a.key();
keys.extend(self.b.key());
keys
}
}

impl<'a, T: Clone + Prefixer<'a> + KeyDeserialize + PrimaryKey<'a>> Prefixer<'a>
for OrderedTuple2<T>
{
fn prefix(&self) -> Vec<Key> {
let mut res = self.a.prefix();
res.extend(self.b.prefix());
res
}
}

impl<
'a,
T: Clone + Prefixer<'a> + KeyDeserialize<Output = T> + PrimaryKey<'a> + PartialEq + PartialOrd,
> KeyDeserialize for OrderedTuple2<T>
{
type Output = OrderedTuple2<T>;

#[inline(always)]
fn from_vec(mut value: Vec<u8>) -> StdResult<Self::Output> {
let mut tu = value.split_off(2);
let t_len = parse_length(&value)?;
let u = tu.split_off(t_len);

Ok(Self::new(T::from_vec(tu)?, T::from_vec(u)?))
}
}

fn parse_length(value: &[u8]) -> StdResult<usize> {
Ok(u16::from_be_bytes(
value
.try_into()
.map_err(|_| StdError::generic_err("Could not read 2 byte length"))?,
)
.into())
}

impl<T> Tuple for OrderedTuple2<T> {
fn arity(&self) -> usize {
2
Expand All @@ -18,9 +77,9 @@ impl<T> Tuple2 for OrderedTuple2<T> {
type Item1 = T;
}

impl<T: PartialOrd + Clone + PartialOrd + PartialEq> From<(T, T)> for OrderedTuple2<T> {
fn from(pair: (T, T)) -> Self {
Self::new(pair.0, pair.1)
impl<T: PartialOrd + Clone + PartialOrd + PartialEq> Into<(T, T)> for OrderedTuple2<T> {
fn into(self) -> (T, T) {
(self.a, self.b)
}
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/cosmwasm/order/src/simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn simulate_cows_via_bank(

// so if not enough was deposited as was taken from original orders, it will fail - so
// solver cannot rob the bank
if order.pair().0 == filled_wanted.denom {
if order.pair().a == filled_wanted.denom {
a_total_from_orders =
a_total_from_orders
.checked_sub(cowed.u128())
Expand Down
9 changes: 4 additions & 5 deletions contracts/cosmwasm/order/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use crate::*;
/// so we need to have several solution per pair to pick one best
pub struct SolutionIndexes<'a> {
/// (token pair secondary index), (stored item), (stored item full key)
pub pair: MultiIndex<'a, DenomPair, SolutionItem, (Denom, Denom, SolverAddress)>,
pub pair: MultiIndex<'a, DenomPair, SolutionItem, (DenomPair, SolverAddress)>,
}

/// (a,b,solver)
/// (DenomPair,SolverAddress) -> SolutionItem
pub type SolutionMultiMap<'a> =
IndexedMap<'a, &'a (Denom, Denom, SolverAddress), SolutionItem, SolutionIndexes<'a>>;
IndexedMap<'a, &'a (DenomPair, SolverAddress), SolutionItem, SolutionIndexes<'a>>;

impl<'a> IndexList<SolutionItem> for SolutionIndexes<'a> {
fn get_indexes(&'_ self) -> Box<dyn Iterator<Item = &'_ dyn Index<SolutionItem>> + '_> {
Expand All @@ -20,8 +20,7 @@ impl<'a> IndexList<SolutionItem> for SolutionIndexes<'a> {
}
}

pub fn solutions<'a>(
) -> IndexedMap<'a, &'a (String, String, String), SolutionItem, SolutionIndexes<'a>> {
pub fn solutions<'a>() -> SolutionMultiMap<'a> {
let indexes = SolutionIndexes {
pair: MultiIndex::new(
|_pk: &[u8], d: &SolutionItem| d.pair.clone(),
Expand Down
15 changes: 6 additions & 9 deletions contracts/cosmwasm/order/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cosmwasm_std::{ensure, BankMsg, Event, StdResult, Uint64, WasmMsg};
use cvm_runtime::{outpost::ExecuteProgramMsg, shared::CvmProgram, AssetId, ExchangeId, NetworkId};

use crate::prelude::*;
use crate::{ordered_tuple::OrderedTuple2, prelude::*};

pub type OrderId = Uint128;

Expand Down Expand Up @@ -175,7 +175,6 @@ pub struct SolutionItem {
pub owner: Addr,
}


impl SolutionItem {
pub fn id(&self) -> Vec<u8> {
solution_id(&(self.owner.to_string(), self.pair.clone(), self.block_added))
Expand Down Expand Up @@ -338,12 +337,10 @@ impl SolvedOrder {
}

pub fn pair(&self) -> DenomPair {
let mut pair = (
DenomPair::new(
self.order.given.denom.clone(),
self.order.msg.wants.denom.clone(),
);
pair.sort_selection();
pair
)
}

pub fn cross_chain(&self) -> u128 {
Expand Down Expand Up @@ -408,7 +405,7 @@ impl CvmFillResult {
}

pub type Denom = String;
pub type DenomPair = (Denom, Denom);
pub type DenomPair = OrderedTuple2<String>;
pub type SolverAddress = String;

pub type CrossChainSolutionKey = (SolverAddress, DenomPair, Block);
Expand All @@ -419,8 +416,8 @@ pub fn solution_id(id: &CrossChainSolutionKey) -> SolutionHash {
use sha2::*;
let mut hash = Sha256::new();
hash.update(id.0.as_bytes());
hash.update(id.1 .0.as_bytes());
hash.update(id.1 .1.as_bytes());
hash.update(id.1.a.as_bytes());
hash.update(id.1.b.as_bytes());
hash.update(id.2.to_be_bytes());
hash.finalize().to_vec()
}

0 comments on commit c3bc234

Please sign in to comment.