Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cvm): using shared code in wasm std target of order contract and sample solutio to cvm traverse #4269

Merged
merged 6 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions code/Cargo.lock

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

1 change: 1 addition & 0 deletions code/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ members = [
"xcvm/cosmwasm/contracts/pingpong",
"xcvm/cosmwasm/tests",
"xcvm/lib/core/",
"xcvm/crates/cvm/"
]
resolver = "2"

Expand Down
2 changes: 1 addition & 1 deletion code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ fn interpret_exchange(
.get_asset_by_id(deps.querier, want.0)
.map_err(ContractError::AssetNotFound)?;

if want.1.amount.is_both() {
if want.1.amount.is_absolute() && want.1.amount.is_ratio() {
return Err(ContractError::CannotDefineBothSlippageAndLimitAtSameTime)
}

Expand Down
12 changes: 7 additions & 5 deletions code/xcvm/cosmwasm/contracts/order/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ edition = "2021"
crate-type = ["cdylib", "rlib"]

[dependencies]
cosmwasm-std = { version = "1.4.1", features = [
cosmwasm-std = { version = "^1.2.5", features = [
"iterator",
], default-features = false }
sylvia = { version = "0.8.1", default-features = false }
sylvia = { version = "^0.6.1", default-features = false }
schemars = { version = "0.8.12", default-features = false }
cosmwasm-schema = { version = "1.4.1", default-features = false }
serde = { version = "1.0.182", default-features = false }
cw-storage-plus = { version = "1.1.0", features = [
cosmwasm-schema = { version = "^1.2.5", default-features = false }
serde = { workspace = true, default-features = false }
cw-storage-plus = { version = "^1.1.0", features = [
"iterator",
], default-features = false }
itertools = { version = "0.11.0", features = [
Expand All @@ -27,3 +27,5 @@ num-rational = { version = "0.4.1", default-features = false, features = [
num-integer = { version = "0.1.45", default-features = false, features = [
"std",
] }

cvm = { path = "../../../crates/cvm", default-features = false, features = ["cosmwasm", "std", "json-schema"]}
96 changes: 78 additions & 18 deletions code/xcvm/cosmwasm/contracts/order/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use cosmwasm_schema::cw_serde;
use cosmwasm_std::{
wasm_execute, Addr, BankMsg, Coin, Event, Order, StdError, Storage, Uint128, Uint64,
};
use cvm::{
instruction::ExchangeId,
shared::{XcInstruction, XcProgram},
};
use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex};
use sylvia::{
contract,
Expand All @@ -15,9 +19,6 @@ use sylvia::{
/// so this is just to make code easy to read, we will optimize later
use num_rational::BigRational;

// fix core in std in contract
// use xc_core::{service::dex::ExchangeId, shared::Displayed, NetworkId};
pub type ExchangeId = Uint128;
pub type Amount = Uint128;
pub type OrderId = Uint128;
pub type NetworkId = u32;
Expand Down Expand Up @@ -87,8 +88,8 @@ pub struct SolutionSubMsg {
pub cows: Vec<Cow>,
/// must adhere Connection.fork_join_supported, for now it is always false (it restrict set of
/// routes possible)
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub routes: Vec<ExchangeRoute>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub route: Option<ExchangeRoute>,

/// after some time, solver will not commit to success
pub timeout: Blocks,
Expand All @@ -98,7 +99,7 @@ pub struct SolutionSubMsg {
#[cw_serde]
pub struct RouteSubMsg {
pub all_orders: Vec<SolvedOrder>,
pub routes: Vec<ExchangeRoute>,
pub route: ExchangeRoute,
}

/// how much of order to be solved by CoW.
Expand Down Expand Up @@ -152,8 +153,8 @@ impl SolvedOrder {
#[cw_serde]
pub struct ExchangeRoute {
// on this chain
pub exchange: Vec<Exchange>,
pub spawn: Vec<Spawn<ExchangeRoute>>,
pub exchanges: Vec<Exchange>,
pub spawns: Vec<Spawn<ExchangeRoute>>,
}

/// Purely transfer route.
Expand All @@ -177,13 +178,14 @@ pub struct Exchange {
pub give: Uint128,
pub want_min: Uint128,
}

pub struct OrderContract<'a> {
pub orders: Map<'a, u128, OrderItem>,
/// (a,b,solver)
pub solutions:
IndexedMap<'a, &'a (Denom, Denom, SolverAddress), SolutionItem, SolutionIndexes<'a>>,
pub next_order_id: Item<'a, u128>,
/// address for CVM contact to send routes to
pub cvm_address: Item<'a, String>,
}

pub type Denom = String;
Expand Down Expand Up @@ -220,6 +222,7 @@ impl Default for OrderContract<'_> {
Self {
orders: Map::new("orders"),
next_order_id: Item::new("next_order_id"),
cvm_address: Item::new("cvm_address"),
solutions: solutions(),
}
}
Expand Down Expand Up @@ -263,17 +266,70 @@ impl OrderContract<'_> {
}

#[msg(exec)]
pub fn route(&self, ctx: ExecCtx, _msg: RouteSubMsg) -> StdResult<Response> {
pub fn route(&self, ctx: ExecCtx, msg: RouteSubMsg) -> StdResult<Response> {
ensure!(
ctx.info.sender == ctx.env.contract.address,
StdError::GenericErr { msg: "only self can call this".to_string() }
);

ctx.deps.api.debug(
"so here we add route execution tracking to storage and map route to CVM program",
);

let _cvm = Self::traverse_route(msg.route);

Ok(Response::default())
}

/// converts high level route to CVM program
fn traverse_route(route: ExchangeRoute) -> cvm::shared::XcProgram {
let mut program = XcProgram {
tag: b"may be use solution id and some chain for tracking".to_vec(),
instructions: vec![],
};

let mut exchanges = Self::traverse_exchanges(route.exchanges);
program.instructions.append(&mut exchanges);

let mut spawns = Self::traverse_spawns(route.spawns);
program.instructions.append(&mut spawns);

program
}

fn traverse_spawns(spawns: Vec<Spawn<ExchangeRoute>>) -> Vec<cvm::shared::XcInstruction> {
let mut result = vec![];
for spawn in spawns {
let spawn = if let Some(execute) = spawn.execute {
let program = Self::traverse_route(execute);
XcInstruction::Spawn {
network_id: spawn.to_chain.into(),
salt: b"solution".to_vec(),
assets: <_>::default(), // map spawn.carry to CVM assets
program,
}
} else {
XcInstruction::Spawn {
network_id: spawn.to_chain.into(),
salt: b"solution".to_vec(),
assets: <_>::default(), // map spawn.carry to CVM assets
program: XcProgram {
tag: b"solution".to_vec(),
instructions: vec![], // we really just do final transfer
},
}
};
result.push(spawn);
}
result
dzmitry-lahoda marked this conversation as resolved.
Show resolved Hide resolved
}

fn traverse_exchanges(_exchanges: Vec<Exchange>) -> Vec<cvm::shared::XcInstruction> {
// here map each exchange to CVM instruction
// for each pool get its denom, and do swaps
vec![]
}

/// Provides solution for set of orders.
/// All fully
#[msg(exec)]
Expand Down Expand Up @@ -351,20 +407,24 @@ impl OrderContract<'_> {
}
}

// send remaining for settlement
let route = wasm_execute(
ctx.env.contract.address,
&ExecMsg::route(RouteSubMsg { all_orders, routes: solution_item.msg.routes }),
vec![],
)?;
let mut response = Response::default();

if let Some(route) = solution_item.msg.route {
// send remaining for settlement
let route = wasm_execute(
ctx.env.contract.address,
&ExecMsg::route(RouteSubMsg { all_orders, route }),
vec![],
)?;
response = response.add_message(route);
};

let solution_chosen = Event::new("mantis-solution-chosen")
.add_attribute("pair", format!("{}{}", a, b))
.add_attribute("solver", ctx.info.sender.to_string());
ctx.deps.api.debug(&format!("mantis-solution-chosen: {:?}", &solution_chosen));
Ok(Response::default()
Ok(response
.add_messages(transfers)
.add_message(route)
.add_event(solution_upserted)
.add_event(solution_chosen))
}
Expand Down
35 changes: 35 additions & 0 deletions code/xcvm/crates/cvm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
edition = "2021"
name = "cvm"
version = "0.1.0"

[build-dependencies]
prost-build = { workspace = true }

[dependencies]
serde = { workspace = true, default-features = false }
derive_more = { workspace = true, default-features = false }
cosmwasm-std = { version = "^1.2.5", default-features = false, optional = true }
schemars = { workspace = true, default-features = false, optional = true }
cosmwasm-schema = { workspace = true, default-features = false, optional = true }
hex = { workspace = true, default-features = false }
num = { workspace = true, default-features = false }

[dev-dependencies]
serde-json-wasm = { version = "1.0.0", default-features = false, features = [
"std",
] }

[features]
default = ["std", "serde", "cosmwasm"]
xcm = []
cosmos = []
cosmwasm = ["serde", "cosmwasm-std"]
substrate = []
scale = []
protobuf = []
json-schema = ["dep:schemars", "cosmwasm-schema"]
ibc = []
evm = []
serde = []
std = ["derive_more/std"]
9 changes: 9 additions & 0 deletions code/xcvm/crates/cvm/clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
disallowed-types = [
# { path = "usize", reason = "variable size" }, # cannot on now, because serde, even if there is no usize in type
{ path = "f64", resdason = "harware dependant" },
{ path = "f32", reason = "harware dependant" },
{ path = "num_traits::float::*", reason = "harware dependant" },
{ path = "serde_json::*", reason = "use serde_json_wasm::*" },
]

disallowed-methods = ["std::time::Duration::as_secs_f64"]
Loading
Loading