Skip to content

Commit

Permalink
Merge pull request #12 from ComposableFi/dz/10
Browse files Browse the repository at this point in the history
feat: split/refactor/tune crates and deps to fit size limit of wasmd
  • Loading branch information
dzmitry-lahoda authored Dec 6, 2023
2 parents be68bd6 + 362a0d2 commit 3d86232
Show file tree
Hide file tree
Showing 65 changed files with 1,184 additions and 1,326 deletions.
594 changes: 34 additions & 560 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ todo = "warn"
let_unit_value = "allow"

[workspace.dependencies]

cvm-runtime = { path = "./crates/cvm-runtime", default-features = false}
cvm-runtime-exchange = { path = "./crates/cvm-runtime-exchange", default-features = false}
derive_more = { version = "0.99.17", default-features = false, features = [
"add",
"add_assign",
Expand Down Expand Up @@ -97,14 +100,15 @@ prost-types = { version = "^0.12.3", default-features = false }
sha2 = { version = "^0.10.8", default-features = false }
num-traits = { version = "^0.2.17", default-features = false }
thiserror = { version = "^1.0.50", default-features = false, package = "thiserror-core" }
xcm = { version = "^5.0.0", default-features = false, package = "staging-xcm" }
# no XCM until it has decent support for cosmwasm and wasm32 std https://github.com/paritytech/polkadot-sdk/pull/1454
# xcm = { version = "^5.0.0", default-features = false, package = "staging-xcm" }
cw-utils = { version = "^1.0.3", default-features = false }
cw2 = { version = "^1.1.2", default-features = false }
ibc-apps-more = { git = "https://github.com/ComposableFi/ibc-apps-more-rs.git", branch = "main", default-features = false }
ibc-apps = { git = "https://github.com/dzmitry-lahoda-forks/ibc-rs.git", branch = "dz/14", default-features = false, features = [
ibc-app-transfer-types = { git = "https://github.com/dzmitry-lahoda-forks/ibc-rs.git", branch = "dz/14", default-features = false, features = [
"serde",
] }
ibc-core = { git = "https://github.com/dzmitry-lahoda-forks/ibc-rs.git", branch = "dz/14", default-features = false, features = [
ibc-core-host-types = { git = "https://github.com/dzmitry-lahoda-forks/ibc-rs.git", branch = "dz/14", default-features = false, features = [
"serde",
] }
ibc-primitives = { git = "https://github.com/dzmitry-lahoda-forks/ibc-rs.git", branch = "dz/14", default-features = false, features = [
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ https://github.com/ComposableFi/composable/tree/main/docs/docs/technology/mantis

## Plan for todayS

1. move CVM shared code here, make it build as part of composable as include src
2. build generator of CVM into contract
3. build storage for solution tacking with is own VW
3. add block to order filled
4. put volume into solution
5. put id into solution

5. split solution contract into algorithms.rs and cw storage deps
6. describe data model of contract
7. finalize porting bruno solver to rust
Expand Down
8 changes: 7 additions & 1 deletion contracts/cosmwasm/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ crate-type = ["cdylib", "rlib"]

[features]
library = []
json-schema = ["ibc-apps-more/json-schema", "cvm-runtime/json-schema"]
json-schema = [
"ibc-apps-more/json-schema",
"cvm-runtime/json-schema",
"cvm-runtime-exchange/json-schema",
]
std = [
"cvm-runtime/std",
"dep:cosmwasm-schema",
"ibc-apps-more/std",
"thiserror/std",
"cvm-runtime-exchange/std",
]
default = ["std"]

[dependencies]
cvm-runtime-exchange ={ workspace = true, default-features = false }
cosmwasm-std = { workspace = true }
cw-storage-plus = { workspace = true }
cosmwasm-schema = { workspace = true, optional = true }
Expand Down
25 changes: 8 additions & 17 deletions contracts/cosmwasm/executor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Note that these events will be yield from the router in production.
### Instantiate contract
```json
{
"type": "wasm-xcvm.executor.instantiated",
"type": "wasm-cvm.executor.instantiated",
"attributes": [
{
"key": "data",
Expand All @@ -28,23 +28,23 @@ Note that these events will be yield from the router in production.
### Execute contract
```json
{
"type": "wasm-xcvm.executor.executed",
"type": "wasm-cvm.executor.executed",
"attributes": [
{
"key": "program",
"value": "{XCVM_PROGRAM_TAG}"
"value": "{CVM_PROGRAM_TAG}"
}
]
}
```

- **XCVM_PROGRAM_TAG**: Tag of the executed XCVM program
- **CVM_PROGRAM_TAG**: Tag of the executed CVM program

### Execute spawn instruction

```json
{
"type": "wasm-xcvm.executor.spawn",
"type": "wasm-cvm.executor.spawn",
"attributes": [
{
"key": "origin_network_id",
Expand All @@ -56,19 +56,19 @@ Note that these events will be yield from the router in production.
},
{
"key": "program",
"value": "{XCVM_PROGRAM}"
"value": "{CVM_PROGRAM}"
}
]
}
```

- **ORIGIN_NETWORK_ID**: Network id of the origin. Eg. Picasso, Ethereum
- **ORIGIN_USER_ID**: Chain agnostic user identifier of the origin. Eg. contract_address in Juno
- **XCVM_PROGRAM**: Json-encoded xcvm program. Note that although it is json-encoded, it is put as a string because of the restrictions of cosmwasm.
- **CVM_PROGRAM**: Json-encoded cvm program. Note that although it is json-encoded, it is put as a string because of the restrictions of cosmwasm.

## Usage

The XCVM interpreter contract interprets the XCVM programs. Available instructions are:
The CVM interpreter contract interprets the CVM programs. Available instructions are:


### Call
Expand All @@ -85,12 +85,3 @@ Queries `gateway`, gets the contract address and then executes that contract to

### Spawn
Emits `spawn` event with the given parameters.

## Compile

```sh
RUSTFLAGS='-C link-arg=-s' cargo b --package=xcvm-interpreter --target=wasm32-unknown-unknown --profile="cosmwasm-contracts"
```

* `-C link-arg=-s` is used for stripping the binary which reduces the binary size drastically.
* `--profile="cosmwasm-contracts"` must be used for cosmwasm contracts.
161 changes: 36 additions & 125 deletions contracts/cosmwasm/executor/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
authenticate::{ensure_owner, Authenticated},
error::{ContractError, Result},
events::*,
msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, Step},
msg::{MigrateMsg, QueryMsg},
state::{self, Config, CONFIG, IP_REGISTER, OWNERS, RESULT_REGISTER, TIP_REGISTER},
};
use alloc::borrow::Cow;
Expand All @@ -11,12 +11,14 @@ use cosmwasm_std::entry_point;
use cosmwasm_std::{
ensure, ensure_eq, to_json_binary, wasm_execute, Addr, BankMsg, Binary, Coin, CosmosMsg, Deps,
DepsMut, Env, MessageInfo, QueryRequest, Reply, Response, StdError, StdResult, SubMsg,
SubMsgResult, WasmQuery, WasmMsg,
SubMsgResult, WasmMsg, WasmQuery,
};
use cvm_runtime::executor::*;
use cvm_runtime::{
apply_bindings,
exchange::*,
executor::{CvmInterpreterInstantiated, InstantiateMsg},
gateway::{AssetReference, BridgeExecuteProgramMsg, BridgeForwardMsg},
service::dex::ExchangeId,
shared, Amount, BindingValue, Destination, Funds, Instruction, NetworkId, Register,
};
use cw2::{ensure_from_older_version, set_contract_version};
Expand All @@ -31,7 +33,12 @@ const SELF_CALL_ID: u64 = 2;
const EXCHANGE_ID: u64 = 3;

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(deps: DepsMut, _env: Env, info: MessageInfo, msg: InstantiateMsg) -> Result {
pub fn instantiate(
deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: cvm_runtime::executor::InstantiateMsg,
) -> Result {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
let gateway_address =
cvm_runtime::gateway::Gateway::addr_validate(deps.api, &msg.gateway_address)?;
Expand All @@ -45,8 +52,14 @@ pub fn instantiate(deps: DepsMut, _env: Env, info: MessageInfo, msg: Instantiate
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> Result {
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: cvm_runtime::executor::ExecuteMsg,
) -> Result {
let token = ensure_owner(deps.as_ref(), &env.contract.address, info.sender.clone())?;
use cvm_runtime::executor::*;
match msg {
ExecuteMsg::Execute { tip, program } => initiate_execution(token, deps, env, tip, program),

Expand Down Expand Up @@ -178,7 +191,7 @@ pub fn handle_execute_step(
exchange_id,
give,
want,
} => interpret_exchange(
} => execute_exchange(
&mut deps,
give,
want,
Expand Down Expand Up @@ -208,7 +221,7 @@ pub fn handle_execute_step(
})
}

fn interpret_exchange(
fn execute_exchange(
deps: &mut DepsMut,
give: Funds,
want: Funds,
Expand All @@ -218,120 +231,21 @@ fn interpret_exchange(
let Config {
gateway_address, ..
} = CONFIG.load(deps.storage)?;
let exchange: cvm_runtime::service::dex::ExchangeItem = gateway_address
let exchange: cvm_runtime::exchange::ExchangeItem = gateway_address
.get_exchange_by_id(deps.querier, exchange_id)
.map_err(ContractError::ExchangeNotFound)?;

use cvm_runtime::service::dex::ExchangeType::*;
use prost::Message;
ensure_eq!(
give.0.len(),
1,
ContractError::OnlySingleAssetExchangeIsSupportedByPool
);
ensure_eq!(
want.0.len(),
1,
ContractError::OnlySingleAssetExchangeIsSupportedByPool
);

let give = give.0[0].clone();
let want = want.0[0].clone();

let asset = gateway_address
.get_asset_by_id(deps.querier, give.0)
.map_err(ContractError::AssetNotFound)?;

let amount: Coin = deps.querier.query_balance(&sender, asset.denom())?;
let amount = give.1.apply(amount.amount.u128())?;
let give: ibc_apps_more::cosmos::Coin = ibc_apps_more::cosmos::Coin {
denom: asset.denom(),
amount: amount.to_string(),
};

let want_asset = gateway_address
.get_asset_by_id(deps.querier, want.0)
.map_err(ContractError::AssetNotFound)?;

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

let response = Response::default()
.add_attribute("exchange_id", exchange_id.to_string());
let response = match exchange.exchange {
OsmosisPoolManagerModuleV1Beta1 { pool_id, .. } => {
let want = if want.1.is_absolute() {
ibc_apps_more::cosmos::Coin {
denom: want_asset.denom(),
amount: want.1.intercept.to_string(),
}
} else {
// use https://github.com/osmosis-labs/osmosis/blob/main/cosmwasm/contracts/swaprouter/src/msg.rs to allow slippage
ibc_apps_more::cosmos::Coin {
denom: want_asset.denom(),
amount: "1".to_string(),
}
};

use cvm_runtime::service::dex::osmosis_std::types::osmosis::poolmanager::v1beta1::*;
use prost::Message;
let msg = MsgSwapExactAmountIn {
routes: vec![SwapAmountInRoute {
pool_id,
token_out_denom: want.denom,
}],

sender: sender.to_string(),
token_in: Some(give),
token_out_min_amount: want.amount,
};
let response = cvm_runtime_exchange::exchange(
give,
want,
gateway_address,
deps,
sender,
&exchange_id,
exchange,
EXCHANGE_ID,
)?;

deps.api
.debug(&format!("cvm::executor::execute::exchange {:?}", &msg));
let msg = CosmosMsg::Stargate {
type_url: MsgSwapExactAmountIn::TYPE_URL.to_string(),
value: Binary::from(msg.encode_to_vec()),
};
let msg = SubMsg::reply_always(msg, EXCHANGE_ID);
response
.add_submessage(msg)
}
AstroportRouterContract {
address,
token_a,
token_b,
} => {
use astroport::{asset::*, router::*};
let (minimum_receive, max_spread) = if want.1.is_absolute() {
(Some(want.1.intercept.into()), None)
} else {
(
None,
Some(cosmwasm_std::Decimal::from_ratio(
(Amount::MAX_PARTS - want.1.slope.0) as u128,
Amount::MAX_PARTS,
)),
)
};
let msg = ExecuteMsg::ExecuteSwapOperations {
operations: vec![SwapOperation::AstroSwap {
offer_asset_info: AssetInfo::NativeToken { denom: give.denom.clone() },
ask_asset_info: AssetInfo::NativeToken { denom: want_asset.denom() },
}],
to: None,
minimum_receive,
max_spread,
};
let msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: address.to_string(),
msg: to_json_binary(&msg)?,
funds: vec![give.try_into().expect("coin")],
});
let msg = SubMsg::reply_always(msg, EXCHANGE_ID);
response.add_submessage(msg)
}
};
Ok(response.add_event(CvmInterpreterExchangeStarted::new(exchange_id)))
}

Expand Down Expand Up @@ -423,7 +337,7 @@ impl<'a> BindingResolver<'a> {
let value = match reference.local {
AssetReference::Cw20 { contract } => contract.into_string(),
AssetReference::Native { denom } => denom,
AssetReference::Erc20 { contract } => contract.to_string(),
// AssetReference::Erc20 { contract } => contract.to_string(),
};
Ok(Cow::Owned(value.into()))
}
Expand All @@ -449,8 +363,7 @@ impl<'a> BindingResolver<'a> {
balance
.apply(coin.amount.into())
.map_err(|_| ContractError::ArithmeticError)?
}
AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
} // AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
};
Ok(Cow::Owned(amount.to_string().into_bytes()))
}
Expand Down Expand Up @@ -490,7 +403,7 @@ pub fn interpret_spawn(
contract,
&env.contract.address,
),
AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
// AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
}?;

if !transfer_amount.is_zero() {
Expand All @@ -511,8 +424,7 @@ pub fn interpret_spawn(
recipient: gateway.address().into(),
amount: transfer_amount.into(),
})?)
}
AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
} // AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
};
}
}
Expand Down Expand Up @@ -580,8 +492,7 @@ pub fn interpret_transfer(
recipient: recipient.clone(),
amount: transfer_amount.into(),
})?)
}
AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
} // AssetReference::Erc20 { .. } => Err(ContractError::AssetUnsupportedOnThisNetwork)?,
};
}

Expand Down
Loading

0 comments on commit 3d86232

Please sign in to comment.