From c8c12a7a8b4b6b5f0e72d6721a67c3203d03a8e3 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 11 Apr 2024 19:32:03 +0100 Subject: [PATCH] magic --- contracts/cosmwasm/order/src/types.rs | 16 ++-- crates/cvm-runtime/src/outpost/query.rs | 2 +- mantis/node/src/bin/mantis.rs | 12 ++- mantis/node/src/bin/simulator.rs | 3 +- mantis/node/src/lib.rs | 1 + mantis/node/src/mantis/blackbox/mod.rs | 93 +++++++++++++++++++++++- mantis/node/src/mantis/cosmos/client.rs | 6 +- mantis/node/src/mantis/cosmos/cvm.rs | 8 +- mantis/node/src/mantis/solve.rs | 2 +- mantis/node/src/solver/cows/optimizer.rs | 5 +- mantis/node/src/solver/cows/solution.rs | 2 +- mantis/node/src/solver/mod.rs | 90 ----------------------- 12 files changed, 131 insertions(+), 109 deletions(-) diff --git a/contracts/cosmwasm/order/src/types.rs b/contracts/cosmwasm/order/src/types.rs index 2a290831..eca0071c 100644 --- a/contracts/cosmwasm/order/src/types.rs +++ b/contracts/cosmwasm/order/src/types.rs @@ -112,6 +112,7 @@ mod test { convert: None, timeout: 1, min_fill: None, + virtual_given: None, }, given: Coin { denom: "given".to_string(), @@ -119,13 +120,15 @@ mod test { }, order_id: 1u128.into(), }; - order.fill(50u128.into(), optimal_price).unwrap(); + order.fill(50u128.into(), optimal_price.into()).unwrap(); assert_eq!(order.given.amount, Uint128::from(50u128)); assert_eq!(order.msg.wants.amount, Uint128::from(50u128)); - order.fill(15u128.into(), optimal_price).unwrap(); + order.fill(15u128.into(), optimal_price.into()).unwrap(); assert_eq!(order.given.amount, Uint128::from(35u128)); assert_eq!(order.msg.wants.amount, Uint128::from(35u128)); - order.fill(Uint128::from(50u128), optimal_price).unwrap(); + order + .fill(Uint128::from(50u128), optimal_price.into()) + .unwrap(); assert_eq!(order.given.amount, Uint128::from(0u128)); assert_eq!(order.msg.wants.amount, Uint128::from(0u128)); @@ -139,6 +142,7 @@ mod test { convert: None, timeout: 1, min_fill: None, + virtual_given: None, }, given: Coin { denom: "given".to_string(), @@ -147,8 +151,10 @@ mod test { order_id: 1u128.into(), }; - assert!(order.fill(500u128.into(), optimal_price).is_err()); - order.fill(50000000u128.into(), optimal_price).unwrap(); + assert!(order.fill(500u128.into(), optimal_price.into()).is_err()); + order + .fill(50000000u128.into(), optimal_price.into()) + .unwrap(); assert_eq!(order.given.amount, Uint128::from(98u128)); } } diff --git a/crates/cvm-runtime/src/outpost/query.rs b/crates/cvm-runtime/src/outpost/query.rs index 3ee330c1..f5bc1ddd 100644 --- a/crates/cvm-runtime/src/outpost/query.rs +++ b/crates/cvm-runtime/src/outpost/query.rs @@ -99,7 +99,7 @@ pub struct GetAssetResponse { pub asset: AssetItem, } -pub type CvmGlt = GetConfigResponse; +pub type CvmGlt = GetConfigResponse; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] diff --git a/mantis/node/src/bin/mantis.rs b/mantis/node/src/bin/mantis.rs index 32d88fa6..ab459755 100644 --- a/mantis/node/src/bin/mantis.rs +++ b/mantis/node/src/bin/mantis.rs @@ -155,7 +155,7 @@ async fn simulate_orders(simulate_args: &SimulateArgs) { .await; } -enum CoinToss{} +enum CoinToss {} impl Get for CoinToss { fn get() -> bool { @@ -189,14 +189,20 @@ async fn get_data_and_solve( None => None, }; - let msgs = solve::(all_orders, signing_key, tip, cvm_glt, router_api).await; + let msgs = mantis_node::mantis::blackbox::solve::( + all_orders, + signing_key, + tip, + cvm_glt, + router_api, + ) + .await; for msg in msgs { send_solution(msg, tip, signing_key, order_contract, rpc, gas).await; } } - async fn send_solution( msg: cw_mantis_order::ExecMsg, tip: &Tip, diff --git a/mantis/node/src/bin/simulator.rs b/mantis/node/src/bin/simulator.rs index 218dc4b2..b99940b8 100644 --- a/mantis/node/src/bin/simulator.rs +++ b/mantis/node/src/bin/simulator.rs @@ -1,5 +1,6 @@ use mantis_cw::OrderSide; -use mantis_node::solver::{orderbook::OrderList, solution::Solution, types::SolverOrder}; +use mantis_node::solver::cows::{orderbook::OrderList, solution::Solution}; +use mantis_node::solver::types::SolverOrder; use mantis_node::{prelude::*, solver::types::Price}; fn main() { diff --git a/mantis/node/src/lib.rs b/mantis/node/src/lib.rs index 56a4f880..c988ec4f 100644 --- a/mantis/node/src/lib.rs +++ b/mantis/node/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(let_chains)] pub mod mantis; pub mod prelude; pub mod solver; diff --git a/mantis/node/src/mantis/blackbox/mod.rs b/mantis/node/src/mantis/blackbox/mod.rs index 0f7ad5d3..7b18779e 100644 --- a/mantis/node/src/mantis/blackbox/mod.rs +++ b/mantis/node/src/mantis/blackbox/mod.rs @@ -1,14 +1,19 @@ use blackbox_rs::{types::*, Client}; +use bounded_collections::Get; /// Given total amount it, order owners and desired out, produce CVM program from and by requesting route use cvm_runtime::{ outpost::GetConfigResponse, shared::{CvmFundsFilter, CvmInstruction, CvmProgram}, Amount, }; +use cw_mantis_order::{CrossChainPart, OrderItem, SolutionSubMsg}; use crate::solver::router::shortest_path; -use super::solve::IntentBankInput; +use super::{ + cosmos::client::Tip, + solve::{find_cows, IntentBankInput, PairSolution}, +}; /// given route and CVM stub with amount, build it to the end fn build_next( @@ -136,3 +141,89 @@ pub async fn get_route( panic!("so need to build instruction so can plug into one program (transaciton)") } } + +pub async fn solve>( + active_orders: Vec, + signing_key: &cosmrs::crypto::secp256k1::SigningKey, + tip: &Tip, + cvm_glt: Option, + router: &String, +) -> Vec { + let cows_per_pair = find_cows(&active_orders); + let mut msgs = vec![]; + for pair_solution in cows_per_pair { + let salt = super::cosmos::cvm::calculate_salt(signing_key, tip, pair_solution.ab.clone()); + let cvm_program = if let Some(ref cvm_glt) = cvm_glt { + let cvm_program = intent_banks_to_cvm_program( + pair_solution.clone(), + &active_orders, + cvm_glt, + router, + &salt, + ) + .await; + + Some(cvm_program) + } else { + None + }; + + // would be reasonable to do do cross chain if it solves some % of whole trade + let route = if let Some(cvm_program) = cvm_program + && Decider::get() + { + Some(CrossChainPart::new( + cvm_program, + salt.clone(), + pair_solution.optimal_price.into(), + )) + } else { + None + }; + let msg = SolutionSubMsg { + cows: pair_solution.cows.clone(), + route, + timeout: tip.timeout(12), + optimal_price: pair_solution.optimal_price.into(), + }; + let msg = cw_mantis_order::ExecMsg::Solve { msg }; + msgs.push(msg); + } + msgs +} + +async fn intent_banks_to_cvm_program( + pair_solution: PairSolution, + all_orders: &Vec, + cvm_glt: &cw_cvm_outpost::msg::GetConfigResponse, + router_api: &String, + salt: &Vec, +) -> CvmProgram { + let (a, b) = IntentBankInput::find_intent_amount( + pair_solution.cows.as_ref(), + all_orders, + pair_solution.optimal_price, + cvm_glt, + pair_solution.ab.clone(), + ); + + log::info!(target:"mantis::solver::", "found for cross chain a: {:?}, b: {:?}", a, b); + + let mut instructions = vec![]; + + if a.in_asset_amount.0.gt(&0) { + let mut a_cvm_route = get_route(router_api, a, cvm_glt, salt.as_ref()).await; + instructions.append(&mut a_cvm_route); + } + if b.in_asset_amount.0.gt(&0) { + let mut b_cvm_route = get_route(router_api, b, cvm_glt, salt.as_ref()).await; + instructions.append(&mut b_cvm_route); + } + log::info!(target: "mantis::solver", "built instructions: {:?}", instructions); + + let cvm_program = CvmProgram { + tag: salt.to_vec(), + instructions, + }; + cvm_program +} diff --git a/mantis/node/src/mantis/cosmos/client.rs b/mantis/node/src/mantis/cosmos/client.rs index 8f56de95..737caebd 100644 --- a/mantis/node/src/mantis/cosmos/client.rs +++ b/mantis/node/src/mantis/cosmos/client.rs @@ -32,11 +32,13 @@ pub struct BlockAgent { impl Debug for BlockAgent { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("BlockAgent").field("tip", &self.tip).field("public_key", &self.key.public_key()).finish() + f.debug_struct("BlockAgent") + .field("tip", &self.tip) + .field("public_key", &self.key.public_key()) + .finish() } } - impl Tip { pub fn timeout(&self, delta: u32) -> u64 { self.block.value() + delta as u64 diff --git a/mantis/node/src/mantis/cosmos/cvm.rs b/mantis/node/src/mantis/cosmos/cvm.rs index 2cc19309..0f00174f 100644 --- a/mantis/node/src/mantis/cosmos/cvm.rs +++ b/mantis/node/src/mantis/cosmos/cvm.rs @@ -4,8 +4,12 @@ use super::client::Tip; /// given key and latest block and sequence number, produces binary salt for cross chain block /// isolating execution of one cross chain transaction from other -pub fn calculate_salt(signing_key: &cosmrs::crypto::secp256k1::SigningKey, tip: &Tip, pair: DenomPair) -> Vec { - use sha2::{Sha256, Digest}; +pub fn calculate_salt( + signing_key: &cosmrs::crypto::secp256k1::SigningKey, + tip: &Tip, + pair: DenomPair, +) -> Vec { + use sha2::{Digest, Sha256}; let mut base = signing_key.public_key().to_bytes().to_vec(); base.extend(tip.block.value().to_be_bytes().to_vec()); base.extend(tip.account.sequence.to_be_bytes().to_vec()); diff --git a/mantis/node/src/mantis/solve.rs b/mantis/node/src/mantis/solve.rs index 54d496bb..d0f14e7e 100644 --- a/mantis/node/src/mantis/solve.rs +++ b/mantis/node/src/mantis/solve.rs @@ -9,7 +9,7 @@ use num_rational::Ratio; use crate::{ prelude::*, - solver::{orderbook::OrderList, solution::Solution}, + solver::cows::{orderbook::OrderList, solution::Solution}, }; /// input batched summarized from users for routing diff --git a/mantis/node/src/solver/cows/optimizer.rs b/mantis/node/src/solver/cows/optimizer.rs index acc55d07..43bb8f14 100644 --- a/mantis/node/src/solver/cows/optimizer.rs +++ b/mantis/node/src/solver/cows/optimizer.rs @@ -2,10 +2,11 @@ use mantis_cw::OrderSide; use rand_distr::num_traits::FromPrimitive; use crate::prelude::*; -use crate::solver::orderbook::*; -use crate::solver::solution::Solution; +use crate::solver::cows::orderbook::*; use crate::solver::types::*; +use super::solution::Solution; + #[derive(Clone, Debug)] pub struct Solver { orders: OrderList, diff --git a/mantis/node/src/solver/cows/solution.rs b/mantis/node/src/solver/cows/solution.rs index 4c3541d1..ac061417 100644 --- a/mantis/node/src/solver/cows/solution.rs +++ b/mantis/node/src/solver/cows/solution.rs @@ -1,5 +1,5 @@ +use super::orderbook::*; use crate::prelude::*; -use crate::solver::orderbook::*; use crate::solver::types::*; #[derive(Clone, Debug)] diff --git a/mantis/node/src/solver/mod.rs b/mantis/node/src/solver/mod.rs index 90a4cfe7..93331fe3 100644 --- a/mantis/node/src/solver/mod.rs +++ b/mantis/node/src/solver/mod.rs @@ -1,93 +1,3 @@ pub mod cows; pub mod router; pub mod types; - - - -async fn solve>( - active_orders: Vec, - signing_key: &cosmrs::crypto::secp256k1::SigningKey, - tip: &Tip, - cvm_glt: Option, - router: &String, -) -> Vec { - let cows_per_pair = mantis_node::mantis::solve::find_cows(&active_orders); - let mut msgs = vec![]; - for pair_solution in cows_per_pair { - let salt = crate::cvm::calculate_salt(signing_key, tip, pair_solution.ab.clone()); - let cvm_program = if let Some(ref cvm_glt) = cvm_glt { - let cvm_program = intent_banks_to_cvm_program( - pair_solution.clone(), - &active_orders, - cvm_glt, - router, - &salt, - ) - .await; - - Some(cvm_program) - } else { - None - }; - - // would be reasonable to do do cross chain if it solves some % of whole trade - let route = if let Some(cvm_program) = cvm_program - && Decider::get() - { - Some(CrossChainPart::new( - cvm_program, - salt.clone(), - pair_solution.optimal_price.into(), - )) - } else { - None - }; - let msg = SolutionSubMsg { - cows: pair_solution.cows.clone(), - route, - timeout: tip.timeout(12), - optimal_price: pair_solution.optimal_price.into(), - }; - let msg = cw_mantis_order::ExecMsg::Solve { msg }; - msgs.push(msg); - } - msgs -} - - - -async fn intent_banks_to_cvm_program( - pair_solution: PairSolution, - all_orders: &Vec, - cvm_glt: &cw_cvm_outpost::msg::GetConfigResponse, - router_api: &String, - salt: &Vec, -) -> CvmProgram { - let (a, b) = mantis_node::mantis::solve::IntentBankInput::find_intent_amount( - pair_solution.cows.as_ref(), - all_orders, - pair_solution.optimal_price, - cvm_glt, - pair_solution.ab.clone(), - ); - - log::info!(target:"mantis::solver::", "found for cross chain a: {:?}, b: {:?}", a, b); - - let mut instructions = vec![]; - - if a.in_asset_amount.0.gt(&0) { - let mut a_cvm_route = blackbox::get_route(router_api, a, cvm_glt, salt.as_ref()).await; - instructions.append(&mut a_cvm_route); - } - if b.in_asset_amount.0.gt(&0) { - let mut b_cvm_route = blackbox::get_route(router_api, b, cvm_glt, salt.as_ref()).await; - instructions.append(&mut b_cvm_route); - } - log::info!(target: "mantis::solver", "built instructions: {:?}", instructions); - - let cvm_program = CvmProgram { - tag: salt.to_vec(), - instructions, - }; - cvm_program -} \ No newline at end of file