Skip to content

Commit

Permalink
feat(cvm): using shared code in wasm std target of order contract and…
Browse files Browse the repository at this point in the history
… sample solutio to cvm traverse (#4269)

need CosmWasm/cosmwasm#1931 . because we depend
on git commit of no_std which cannot be ^ compiled with version upper of
std exporting functions (until patching std not to export, hacks)

Required for merge:
- [ ] `pr-workflow-check / draft-release-check` is ✅ success
- Other rules GitHub shows you, or can be read in
[configuration](../terraform/github.com/branches.tf)

Makes review faster:
- [ ] PR title is my best effort to provide summary of changes and has
clear text to be part of release notes
- [ ] I marked PR by `misc` label if it should not be in release notes
- [ ] Linked Zenhub/Github/Slack/etc reference if one exists
- [ ] I was clear on what type of deployment required to release my
changes (node, runtime, contract, indexer, on chain operation, frontend,
infrastructure) if any in PR title or description
- [ ] Added reviewer into `Reviewers`
- [ ] I tagged(`@`) or used other form of notification of one person who
I think can handle best review of this PR
- [ ] I have proved that PR has no general regressions of relevant
features and processes required to release into production
- [ ] Any dependency updates made, was done according guides from
relevant dependency
- Clicking all checkboxes 
- Adding detailed description of changes when it feels appropriate (for
example when PR is big)
  • Loading branch information
dzmitry-lahoda authored Nov 1, 2023
1 parent 05c79dc commit 1277234
Show file tree
Hide file tree
Showing 18 changed files with 1,309 additions and 33 deletions.
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
}

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

0 comments on commit 1277234

Please sign in to comment.