Skip to content

Commit

Permalink
seems final solution
Browse files Browse the repository at this point in the history
  • Loading branch information
dzmitry-lahoda committed Mar 14, 2024
1 parent 717cb88 commit b205fbf
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 72 deletions.
6 changes: 6 additions & 0 deletions contracts/cosmwasm/order/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

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

/// count of solutions at minimum which can be decided, just set 1 for ease of devtest
pub const MIN_SOLUTION_COUNT: u32 = 1;
4 changes: 0 additions & 4 deletions contracts/cosmwasm/order/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ pub fn filled_order_cannot_be_cross_chain_routed() -> StdError {
StdError::generic_err("Filled order cannot be cross chain routed")
}



pub fn partial_cross_chain_not_implemented() -> StdError {
StdError::generic_err("Partial cross chain not implemented")
}


7 changes: 2 additions & 5 deletions contracts/cosmwasm/order/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,11 @@ pub mod order {
.add_attribute("solution_block_added", solution_block_added.to_string())
}

pub fn mantis_order_routed_full(
order: &OrderItem,
solver_address: &String,
) -> Event {
pub fn mantis_order_routed_full(order: &OrderItem, solver_address: &String) -> Event {
Event::new("mantis-order-routed-full")
.add_attribute("order_id", order.order_id.to_string())
.add_attribute("solver_address", solver_address.clone())
}
}
}

pub mod solution {
Expand Down
137 changes: 88 additions & 49 deletions contracts/cosmwasm/order/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(clippy::disallowed_methods)] // does unwrap inside
#![allow(deprecated)] // sylvia macro

mod constants;
mod errors;
mod events;
mod prelude;
Expand Down Expand Up @@ -38,11 +39,14 @@ pub struct OrderContract<'a> {
/// address for CVM contact to send routes to
pub cvm_address: Item<'a, String>,
pub admin: cw_controllers::Admin<'a>,
/// block on which pair got some solution
pub pair_to_block: Map<'a, DenomPair, Block>,
}

impl Default for OrderContract<'_> {
fn default() -> Self {
Self {
pair_to_block: Map::new("pair_to_block"),
tracked_orders: Map::new("tracked_orders"),
orders: Map::new("orders"),
next_order_id: Item::new("next_order_id"),
Expand Down Expand Up @@ -188,35 +192,45 @@ impl OrderContract<'_> {

let contract = self.cvm_address.load(ctx.deps.storage)?;

// let cvm_filled = self.pre_fill_remotely(
// ctx.branch(),
// ctx.deps.storage,
// msg.msg.optimal_price,
// msg.solver_address,
// msg.solution_id,
// msg.solved_orders,
// msg.pair.clone(),
// )?;

// let funds = vec![
// Coin {
// denom: msg.pair.0,
// amount: a_taken.into(),
// },
// Coin {
// denom: msg.pair.1,
// amount: b_taken.into(),
// },
// ];
// let cvm = wasm_execute(contract, &cvm, funds)?;
// //trust_fill();
// Ok(Response::default().add_message(cvm))
let cvm_filled = self.pre_fill_remotely(
ctx.branch(),
msg.msg.optimal_price,
msg.solver_address,
msg.solution_id,
msg.solved_orders,
msg.pair.clone(),
)?;

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

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

let funds = vec![
Coin {
denom: msg.pair.0,
amount: a_funds,
},
Coin {
denom: msg.pair.1,
amount: b_funds,
},
];
let cvm = wasm_execute(contract, &cvm, funds)?;
Ok(Response::default().add_message(cvm))
}

/// Provides solution for set of orders.
/// All fully
#[msg(exec)]
pub fn settle(&self, ctx: ExecCtx, msg: SolutionSubMsg) -> StdResult<Response> {
pub fn settle(&self, mut ctx: ExecCtx, msg: SolutionSubMsg) -> StdResult<Response> {
// read all orders as solver provided
let mut all_orders = join_solution_with_orders(&self.orders, &msg, &ctx)?;
let at_least_one = all_orders.first().expect("at least one");
Expand All @@ -236,15 +250,16 @@ impl OrderContract<'_> {
owner: ctx.info.sender.clone(),
};

self.solutions.save(
ctx.deps.storage,
&(
ab.clone().0,
ab.clone().1,
ctx.info.sender.clone().to_string(),
),
&possible_solution,
)?;
self.start_solution(ctx.branch(), ab.clone())?;

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

self.solutions
.save(ctx.deps.storage, &solution_key, &possible_solution)?;
let solution_upserted = mantis_solution_upserted(&ab, &ctx);

ctx.deps.api.debug(&format!(
Expand All @@ -264,6 +279,18 @@ impl OrderContract<'_> {
.api
.debug(&format!("mantis::solutions::current {:?}", all_solutions));

/// wait before solve
let started = self
.pair_to_block
.load(ctx.deps.storage, ab.clone())
.expect("pair to block");

if started + constants::BATCH_EPOCH as u64 > ctx.env.block.height {
return Ok(Response::default());
} else {
self.pair_to_block.remove(ctx.deps.storage, ab.clone());
}

// pick up optimal solution with solves with bank
let mut a_in = 0u128;
let mut b_in = 0u128;
Expand Down Expand Up @@ -338,13 +365,13 @@ impl OrderContract<'_> {

self.solutions.clear(ctx.deps.storage);
let solution_chosen = emit_solution_chosen(
ab,
ctx,
ab.clone(),
ctx.branch(),
&after_cows,
volume,
cross_chain_b,
cross_chain_a,
solution_item,
solution_item.clone(),
);

for transfer in after_cows {
Expand Down Expand Up @@ -372,6 +399,19 @@ impl OrderContract<'_> {
.add_event(solution_chosen))
}

fn start_solution(&self, mut ctx: ExecCtx<'_>, ab: DenomPair) -> Result<(), StdError> {
Ok(
if self
.pair_to_block
.load(ctx.deps.storage, ab.clone())
.is_err()
{
self.pair_to_block
.save(ctx.deps.storage, ab, &ctx.env.block.height)?;
},
)
}

/// Simple get all orders
#[msg(query)]
pub fn get_all_orders(&self, ctx: QueryCtx) -> StdResult<Vec<OrderItem>> {
Expand Down Expand Up @@ -471,40 +511,39 @@ impl OrderContract<'_> {
fn pre_fill_remotely<'a>(
&self,
ctx: ExecCtx<'a>,
storage: &mut dyn Storage,
optimal_price: Ratio,
solver_address: String,
solution_id: SolutionHash,
solver_orders: Vec<SolvedOrder>,
pair: DenomPair,
) -> Result<Vec<CvmFillResult>, StdError> {
let mut result = vec![];
let mut result = vec![];
for order in solver_orders.iter() {
if let Some(cross_chain_part) = order.solution.cross_chain_part {
match cross_chain_part {
OrderAmount::Part(_, _) => return Err(errors::partial_cross_chain_not_implemented()),
OrderAmount::Part(_, _) => {
return Err(errors::partial_cross_chain_not_implemented())
}
OrderAmount::All => {
let event = mantis_order_routed_full(&order, &solver_address);
let event = mantis_order_routed_full(&order.order, &solver_address);
let tracker = TrackedOrderItem {
order_id: order.order.order_id,
solution_id: solution_id.clone(),
amount_taken: order.given().amount.u128(),
amount_taken: order.given().clone(),
// so we expect promised to be same as remaining.
// no really flexible
// really it must allow CoWs to violate limits,
// fixed by CVM later
// but bruno described differently, so we stick with that
// but bruno described differently, so we stick with that
promised: order.wants().amount,
};
self.orders.remove(storage, order.order.order_id.u128());
result.push(CvmFillResult::new(
tracker,
event,
));
self.orders
.remove(ctx.deps.storage, order.order.order_id.u128());
result.push(CvmFillResult::new(tracker, event));
}
}
}
}
}
}
Ok(result)
}
}
Expand Down
10 changes: 7 additions & 3 deletions contracts/cosmwasm/order/src/simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ use crate::CowSolutionCalculation;
use crate::Filling;
use crate::SolvedOrder;


/// given expected output amount and list of orders and CVM program, produce fill in of orders
/// return filling amounts for all orders from program, which may or may not lead to full fill
pub fn verify(route: CvmProgram, in_asset: &AssetItem, out_asset:&AssetItem, predicted_out_amount : u128, orders: Vec<SolvedOrder>) -> Result<Vec<Filling>, StdError> {

pub fn verify(
route: CvmProgram,
in_asset: &AssetItem,
out_asset: &AssetItem,
predicted_out_amount: u128,
orders: Vec<SolvedOrder>,
) -> Result<Vec<Filling>, StdError> {
panic!()
}

Expand Down
15 changes: 4 additions & 11 deletions contracts/cosmwasm/order/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ pub struct CowSolutionCalculation {
pub filled: Vec<CowFilledOrder>,
}

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

/// count of solutions at minimum which can be decided, just set 1 for ease of devtest
pub const MIN_SOLUTION_COUNT: u32 = 1;

/// parts of a whole, numerator / denominator
pub type Ratio = (Uint64, Uint64);

Expand Down Expand Up @@ -251,7 +245,7 @@ pub struct SubWasmMsg<Payload> {
feature = "json-schema", // all(feature = "json-schema", not(target_arch = "wasm32")),
derive(schemars::JsonSchema)
)]
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Copy)]
#[serde(rename_all = "snake_case")]
pub enum OrderAmount {
/// whole remaining amount in order
Expand Down Expand Up @@ -309,7 +303,7 @@ impl SolvedOrder {
None => 0u128.into(),
}
}

pub fn wants_cross_chain(&self) -> Amount {
match self.solution.cross_chain_part {
Some(x) => match x {
Expand All @@ -331,7 +325,7 @@ impl SolvedOrder {
pub struct TrackedOrderItem {
pub order_id: OrderId,
pub solution_id: SolutionHash,
pub amount_taken: Amount,
pub amount_taken: Coin,
pub promised: Amount,
}

Expand Down Expand Up @@ -406,13 +400,12 @@ impl CvmFillResult {
pub fn new(tracking: TrackedOrderItem, event: Event) -> Self {
Self {
tracking,
remaining : None,
remaining: None,
event,
}
}
}


pub type Denom = String;
pub type DenomPair = (Denom, Denom);
pub type SolverAddress = String;
Expand Down

0 comments on commit b205fbf

Please sign in to comment.