From 170d7b8734501a2fa9b435637cb81254481f0f19 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 16:01:44 +0100 Subject: [PATCH 01/11] added docs about assets ids and stride --- code/xcvm/README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/code/xcvm/README.md b/code/xcvm/README.md index 8462fc886e8..e346a211faf 100644 --- a/code/xcvm/README.md +++ b/code/xcvm/README.md @@ -57,6 +57,22 @@ Can be considered as 3 layers, For each chain and protocol it makes pragmatics hacks to use existing liquidity and execution primitives. +### Examples + +#### Stake on Strides + +Program to `Stake` on Stride and transfer staked token to Osmosis +is detected as pattern expressed in XCVM. + +That part of program is translated to IBC calls to Stride without contracts deployed. + +So this program is possible +``` +Osmosis ATOM -> +Spawn(Stride, ATOM) -> Stake(ATOM) + Spawn(Osmosis, stATOM) +-> Spawn(Centauri, stATOM) +``` + ### ICS-20 Memo as `Spawn` carrier `Spawn` forms `ICS-20` packet with `memo`. @@ -69,4 +85,14 @@ For each chain and protocol it makes pragmatics hacks to use existing liquidity `xc-master` contract verifies amount sent and proceed with move of assets up to amount in message via delegation from `xc-account`. -Approach is needed because there is no `amount` information can be securely transferred in `memo`. \ No newline at end of file +Approach is needed because there is no `amount` information can be securely transferred in `memo`. + +### Asset id encoding + +Each asset id is 128 bit number with 4 first bytes are network id, means that numbers never overlap. + +So it will not be the case that on one chain 123213 means PEPA and on other chain 123213 means SHIB. + +Prefix allows to find network to look at for asset info. + +For security reasons when assets sent from chain to chain, asset id changes. \ No newline at end of file From 19993d9569da252997269c26184a293fb1ab41e3 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 16:22:12 +0100 Subject: [PATCH 02/11] improved assets event + addeed some test of hashes to use in devnet --- .../xcvm/cosmwasm/contracts/gateway/README.md | 3 ++ .../cosmwasm/contracts/gateway/src/assets.rs | 4 +-- code/xcvm/lib/core/src/cosmos.rs | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/README.md b/code/xcvm/cosmwasm/contracts/gateway/README.md index cab61fc2698..1c9945f4493 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/README.md +++ b/code/xcvm/cosmwasm/contracts/gateway/README.md @@ -7,3 +7,6 @@ Hides custom entry points and messaging under unified security, routing, assets Is Entrypoint and exit for Programs. Also handles interactions with [OTP](otp.md). Book keeps per-chain state. Holds the address mappings for cross-chain accounts and instantiates new interpreters. + + +## Handling cases when there is no contract \ No newline at end of file diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs index db284ba6a37..1c1f16bb9bc 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs @@ -38,5 +38,5 @@ pub(crate) fn force_remove_asset( ) -> std::result::Result { ASSETS.remove(deps.storage, asset_id); Ok(Response::new() - .add_event(make_event("unregister").add_attribute("asset_id", asset_id.to_string()))) -} + .add_event(make_event("assets.removed").add_attribute("asset_id", asset_id.to_string()))) +} \ No newline at end of file diff --git a/code/xcvm/lib/core/src/cosmos.rs b/code/xcvm/lib/core/src/cosmos.rs index 3488e33eebc..4b869f1b419 100644 --- a/code/xcvm/lib/core/src/cosmos.rs +++ b/code/xcvm/lib/core/src/cosmos.rs @@ -23,3 +23,32 @@ pub fn hash_denom_trace(unwrapped: &str) -> String { let digest = Sha256::digest(unwrapped.as_bytes()); ["ibc/", &hex::encode_upper(digest)].concat() } + +#[cfg(test)] +mod tests { + use super::*; + + // various devnet channels hashes + #[test] + fn devnet() { + let pica = hash_denom_trace("/transfer/channel-1/1"); + assert_eq!(pica, "ibc/B62D63F2BD5A7B70AB15F84BCB70EAC88222D3A8E8E0B22793EE788068EA22BA"); + let pica = hash_denom_trace("/transfer/channel-0/1"); + assert_eq!(pica, "ibc/F2B6EF5B6F86990A3863B78687ADE3D95E412657AAEB7CF2B3B8131B8055C1F1"); + + let pica: String = hash_denom_trace("/transfer/channel-1/ppica"); + assert_eq!(pica, "ibc/661BD30059657725608DF36907F06B70C1FA7A1772FF92AEE1844A3E35A80D63"); + + let pica: String = hash_denom_trace("/transfer/channel-0/ppica"); + assert_eq!(pica, "ibc/F0E228914E0E69E7B5E9231282FE6B7595CF90CB76E7193C6AFDCACDF5E83821"); + + let osmo: String = hash_denom_trace("/transfer/channel-1/uosmo"); + assert_eq!(osmo, "ibc/BCACECE44E39A9009D793D68CC5DF76B402607B1C574379DCB4F3A5D24BC1936"); + + let osmo: String = hash_denom_trace("/transfer/channel-0/uosmo"); + assert_eq!(osmo, "ibc/B4511F40A2844906F5940444691EE3AE877E8E0DD8354C8C4D36670A46C5680D"); + + } +} + + From 9253eaeb3c2d9c6fa2bf310370e15ab43fc99172 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 16:47:06 +0100 Subject: [PATCH 03/11] so we have asset ids --- code/xcvm/lib/core/src/asset.rs | 36 +++++++++++++++++++++++- code/xcvm/lib/core/src/gateway/config.rs | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/code/xcvm/lib/core/src/asset.rs b/code/xcvm/lib/core/src/asset.rs index f19e8533a8e..39a1aa30459 100644 --- a/code/xcvm/lib/core/src/asset.rs +++ b/code/xcvm/lib/core/src/asset.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{prelude::*, NetworkId}; #[cfg(feature = "cw-storage-plus")] use cw_storage_plus::{Key, Prefixer}; @@ -402,3 +402,37 @@ impl From> for Vec<(u128, T)> { .collect() } } + +pub fn generate_asset_id(network_id: NetworkId, protocol_id: u32, nonce: u64) -> AssetId { + [ + network_id.0.to_be_bytes().to_vec(), + protocol_id.to_be_bytes().to_vec(), + nonce.to_be_bytes().to_vec(), + ] + .concat() + .try_into() + .map(u128::from_be_bytes) + .expect("[u8; 8] + bytes(u64) = [u8; 16]") + .into() +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn devnet() { + let pica = generate_asset_id(0.into(), 0, 1); + assert_eq!(pica, 1.into()); + let pica = generate_asset_id(1.into(), 0, 1); + assert_eq!(pica, 79228162514264337593543950337.into()); + let pica = generate_asset_id(2.into(), 0, 1); + assert_eq!(pica, 158456325028528675187087900673.into()); + let pica = generate_asset_id(3.into(), 0, 1); + assert_eq!(pica, 237684487542793012780631851009.into()); + + let atom = generate_asset_id(2.into(), 0, 2); + assert_eq!(atom, 158456325028528675187087900674.into()); + let atom = generate_asset_id(3.into(), 0, 2); + assert_eq!(atom, 237684487542793012780631851010.into()); + } +} diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index 48b5ea3f997..28dbf0fbe7c 100644 --- a/code/xcvm/lib/core/src/gateway/config.rs +++ b/code/xcvm/lib/core/src/gateway/config.rs @@ -127,6 +127,7 @@ pub struct OtherNetworkItem { /// and about assets and services on these chains /// (in future block hooks and some set of host extensions/precompiles would help to get some info /// automatically) +/// `Force` message sets the data unconditionally. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] From b1ba1e1c003813c19cfb97824fe95635907d7918 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 17:24:51 +0100 Subject: [PATCH 04/11] bashin assets --- code/xcvm/lib/core/src/gateway/config.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index 28dbf0fbe7c..ac7c8f9578a 100644 --- a/code/xcvm/lib/core/src/gateway/config.rs +++ b/code/xcvm/lib/core/src/gateway/config.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::IbcTimeout; +use cosmwasm_std::{IbcTimeout, HexBinary}; use ibc_rs_scale::core::ics24_host::identifier::ChannelId; use crate::{ @@ -34,6 +34,7 @@ pub struct Ics20Features { #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] #[cfg_attr(feature = "std", derive(JsonSchema))] pub enum ForeignAssetId { IbcIcs20(PrefixedDenom), @@ -205,12 +206,14 @@ pub struct BridgeAsset { #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] pub enum AssetReference { Native { denom: String }, - Virtual { cw20_address: Addr }, + ADR001 { sha256: HexBinary }, + Cw20 { contract: Addr }, } impl AssetReference { pub fn denom(&self) -> String { match self { + AssetReference::ADR001 { sha256 } => ["ibc/", sha256].concat().to_owned(), AssetReference::Native { denom } => denom.clone(), AssetReference::Virtual { cw20_address } => ["cw20:", cw20_address.as_str()].concat(), } From 5bf0eb3987bd443194d48d31d4f58b75b6e8b1ef Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 17:49:19 +0100 Subject: [PATCH 05/11] finalized --- code/Cargo.lock | 1 + .../contracts/gateway/src/contract/execute.rs | 8 +- .../contracts/interpreter/src/contract.rs | 30 +- code/xcvm/lib/core/Cargo.toml | 3 + code/xcvm/lib/core/schema/raw/execute.json | 229 +++++++++----- .../xcvm/lib/core/schema/raw/instantiate.json | 4 +- code/xcvm/lib/core/schema/raw/query.json | 2 +- .../schema/raw/response_to_lookup_asset.json | 46 ++- code/xcvm/lib/core/schema/xc-core.json | 281 ++++++++++++------ code/xcvm/lib/core/src/gateway/config.rs | 28 +- code/xcvm/lib/core/src/location.rs | 31 -- 11 files changed, 431 insertions(+), 232 deletions(-) delete mode 100644 code/xcvm/lib/core/src/location.rs diff --git a/code/Cargo.lock b/code/Cargo.lock index 0d09d554612..5aa202017da 100644 --- a/code/Cargo.lock +++ b/code/Cargo.lock @@ -19230,6 +19230,7 @@ dependencies = [ "sha2 0.10.7", "strum 0.25.0", "thiserror-core", + "xcm", ] [[package]] diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index 42fe925437d..a093bb43569 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -97,8 +97,8 @@ fn transfer_from_user( return Err(ContractError::InsufficientFunds)? } }, - msg::AssetReference::Virtual { cw20_address } => - transfers.push(Cw20Contract(cw20_address).call(Cw20ExecuteMsg::TransferFrom { + msg::AssetReference::Cw20 { contract } => + transfers.push(Cw20Contract(contract).call(Cw20ExecuteMsg::TransferFrom { owner: user.to_string(), recipient: self_address.to_string(), amount: (*amount).into(), @@ -232,8 +232,8 @@ fn send_funds_to_interpreter( amount: vec![Coin::new(amount, denom)], } .into(), - msg::AssetReference::Virtual { cw20_address } => { - let contract = Cw20Contract(cw20_address); + msg::AssetReference::Cw20 { contract } => { + let contract = Cw20Contract(contract); contract.call(Cw20ExecuteMsg::Transfer { recipient: interpreter_address.clone(), amount: amount.into(), diff --git a/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs b/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs index ab78b8009a7..397df98be74 100644 --- a/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs +++ b/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs @@ -230,8 +230,8 @@ pub fn interpret_call( asset_id, )?; match reference.local { - AssetReference::Virtual { cw20_address } => - Cow::Owned(cw20_address.into_string().into()), + AssetReference::Cw20 { contract } => + Cow::Owned(contract.into_string().into()), AssetReference::Native { denom } => Cow::Owned(denom.into()), } }, @@ -242,10 +242,10 @@ pub fn interpret_call( asset_id, )?; let amount = match reference.local { - AssetReference::Virtual { cw20_address } => apply_amount_to_cw20_balance( + AssetReference::Cw20 { contract } => apply_amount_to_cw20_balance( deps, &balance, - &cw20_address, + &contract, &env.contract.address, ), AssetReference::Native { denom } => @@ -308,10 +308,10 @@ pub fn interpret_spawn( .apply(coin.amount.into()) .map_err(|_| ContractError::ArithmeticError) }, - AssetReference::Virtual { cw20_address } => apply_amount_to_cw20_balance( + AssetReference::Cw20 { contract } => apply_amount_to_cw20_balance( deps.as_ref(), &balance, - cw20_address, + contract, &env.contract.address, ), }?; @@ -324,8 +324,8 @@ pub fn interpret_spawn( to_address: gateway_address.clone().into(), amount: vec![Coin { denom, amount: transfer_amount.into() }], }), - AssetReference::Virtual { cw20_address } => response.add_message( - Cw20Contract(cw20_address).call(Cw20ExecuteMsg::Transfer { + AssetReference::Cw20 { contract } => response.add_message( + Cw20Contract(contract).call(Cw20ExecuteMsg::Transfer { recipient: gateway_address.clone().into(), amount: transfer_amount.into(), })?, @@ -396,12 +396,12 @@ pub fn interpret_transfer( amount: vec![coin], }) }, - AssetReference::Virtual { cw20_address } => { - let contract = Cw20Contract(cw20_address.clone()); + AssetReference::Cw20 { contract } => { + let contract = Cw20Contract(contract.clone()); let transfer_amount = apply_amount_to_cw20_balance( deps.as_ref(), &balance, - &cw20_address, + &contract.0, &env.contract.address, )?; response.add_message(contract.call(Cw20ExecuteMsg::Transfer { @@ -463,17 +463,17 @@ fn handle_call_result(deps: DepsMut, msg: Reply) -> StdResult { /// Calculates and returns the actual balance to process /// /// * `balance`: Balance to be transformed into the actual balance -/// * `cw20_address`: Address of the corresponding cw20 contract +/// * `contract`: Address of the corresponding cw20 contract /// * `self_address`: This interpreter's address fn apply_amount_to_cw20_balance + Clone>( deps: Deps, balance: &Balance, - cw20_address: A, + contract: A, self_address: A, ) -> Result { let balance_response = deps.querier.query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: cw20_address.clone().into(), + contract_addr: contract.clone().into(), msg: to_binary(&Cw20QueryMsg::Balance { address: self_address.into() })?, }))?; @@ -481,7 +481,7 @@ fn apply_amount_to_cw20_balance + Clone>( // If the balance is unit, we need to take `decimals` into account. let token_info = deps.querier.query::(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: cw20_address.into(), + contract_addr: contract.into(), msg: to_binary(&Cw20QueryMsg::TokenInfo {})?, }))?; balance diff --git a/code/xcvm/lib/core/Cargo.toml b/code/xcvm/lib/core/Cargo.toml index 7997b8df8db..1cb18713125 100644 --- a/code/xcvm/lib/core/Cargo.toml +++ b/code/xcvm/lib/core/Cargo.toml @@ -27,6 +27,7 @@ strum.workspace = true thiserror = { workspace = true } ibc-proto = { workspace = true, default-features = false, features = ["serde", "parity-scale-codec"]} serde-cw-value = { workspace = true, default-features = false} +xcm = { workspace = true, default-features = false, optional = true} [build-dependencies] prost-build = { workspace = true } @@ -34,8 +35,10 @@ prost-build = { workspace = true } [features] default = ["std"] cosmwasm = ["cw-storage-plus", "cw20"] +substrate = ["xcm"] std = [ "cosmwasm-std/std", + "xcm/std", "cw-storage-plus/std", "dep:cosmwasm-schema", "dep:schemars", diff --git a/code/xcvm/lib/core/schema/raw/execute.json b/code/xcvm/lib/core/schema/raw/execute.json index d15b720a220..ef7825e9195 100644 --- a/code/xcvm/lib/core/schema/raw/execute.json +++ b/code/xcvm/lib/core/schema/raw/execute.json @@ -117,7 +117,7 @@ ], "properties": { "message_hook": { - "$ref": "#/definitions/MessageHookMsg" + "$ref": "#/definitions/XcMessageData" } }, "additionalProperties": false @@ -155,11 +155,14 @@ "AssetItem": { "type": "object", "required": [ + "asset_id", "from_network_id", - "id", "local" ], "properties": { + "asset_id": { + "$ref": "#/definitions/AssetId" + }, "bridged": { "anyOf": [ { @@ -173,9 +176,6 @@ "from_network_id": { "$ref": "#/definitions/NetworkId" }, - "id": { - "$ref": "#/definitions/AssetId" - }, "local": { "$ref": "#/definitions/AssetReference" } @@ -207,16 +207,36 @@ { "type": "object", "required": [ - "virtual" + "a_d_r001" + ], + "properties": { + "a_d_r001": { + "type": "object", + "required": [ + "sha256" + ], + "properties": { + "sha256": { + "$ref": "#/definitions/HexBinary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" ], "properties": { - "virtual": { + "cw20": { "type": "object", "required": [ - "cw20_address" + "contract" ], "properties": { - "cw20_address": { + "contract": { "$ref": "#/definitions/Addr" } } @@ -423,33 +443,36 @@ } }, "ConfigSubMsg": { + "description": "cross cross chain routing requires a lot of configuration, about chain executing this contract, about connectivity to and of other chains (even if not connected directly) and about assets and services on these chains (in future block hooks and some set of host extensions/precompiles would help to get some info automatically) `Force` message sets the data unconditionally.", "oneOf": [ { + "description": "Permissioned message (gov or admin) to force set information about network contract is executed. Network can be any network or this network (so it overrides some this network parameters too)", "type": "object", "required": [ - "force_network_to_network" + "force_network" ], "properties": { - "force_network_to_network": { - "$ref": "#/definitions/ForceNetworkToNetworkMsg" + "force_network": { + "$ref": "#/definitions/NetworkItem" } }, "additionalProperties": false }, { + "description": "Sets network to network connectivity/routing information", "type": "object", "required": [ - "force_network" + "force_network_to_network" ], "properties": { - "force_network": { - "$ref": "#/definitions/NetworkItem" + "force_network_to_network": { + "$ref": "#/definitions/ForceNetworkToNetworkMsg" } }, "additionalProperties": false }, { - "description": "Message sent by an admin to register a new asset.", + "description": "Permissioned message (gov or admin) to force set asset information.", "type": "object", "required": [ "force_asset" @@ -510,7 +533,7 @@ ] }, "Displayed_for_uint128": { - "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", + "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json_wasm::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json_wasm::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", "type": "integer", "format": "uint128", "minimum": 0.0 @@ -580,10 +603,10 @@ { "type": "object", "required": [ - "IbcIcs20" + "ibc_ics20" ], "properties": { - "IbcIcs20": { + "ibc_ics20": { "$ref": "#/definitions/PrefixedDenom" } }, @@ -635,31 +658,63 @@ ], "properties": { "cosm_wasm": { - "$ref": "#/definitions/Addr" + "type": "object", + "required": [ + "admin", + "contract", + "interpreter_code_id" + ], + "properties": { + "admin": { + "description": "admin of everything", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "contract": { + "$ref": "#/definitions/Addr" + }, + "interpreter_code_id": { + "description": "Address of the XCVM interpreter contract code", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } } }, "additionalProperties": false } ] }, - "IbcEnabled": { + "HexBinary": { + "description": "This is a wrapper around Vec to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also .", + "type": "string" + }, + "IbcChannels": { "type": "object", "properties": { - "ics_20_features": { + "ics20": { "anyOf": [ { - "$ref": "#/definitions/Ics20Features" + "$ref": "#/definitions/Ics20Channel" }, { "type": "null" } ] - }, - "ics_20_sender": { - "description": "specific per chain way to send IBC ICS 20 assets", + } + } + }, + "IbcEnabled": { + "type": "object", + "properties": { + "channels": { "anyOf": [ { - "$ref": "#/definitions/IbcIcs20Sender" + "$ref": "#/definitions/IbcChannels" }, { "type": "null" @@ -688,8 +743,8 @@ { "type": "string", "enum": [ - "OsmosisModule", - "CosmWasmStd" + "CosmosStargateIbcApplicationsTransferV1MsgTransfer", + "CosmWasmStd1_3" ] }, { @@ -754,7 +809,34 @@ } } }, + "Ics20Channel": { + "type": "object", + "required": [ + "sender" + ], + "properties": { + "features": { + "anyOf": [ + { + "$ref": "#/definitions/Ics20Features" + }, + { + "type": "null" + } + ] + }, + "sender": { + "description": "specific per chain way to send IBC ICS 20 assets", + "allOf": [ + { + "$ref": "#/definitions/IbcIcs20Sender" + } + ] + } + } + }, "Ics20Features": { + "description": "what features/modules/version enabled/installed/configured", "type": "object", "properties": { "pfm": { @@ -780,6 +862,22 @@ } } }, + "IcsPair": { + "description": "we need both, so we can unwrap", + "type": "object", + "required": [ + "sink", + "source" + ], + "properties": { + "sink": { + "$ref": "#/definitions/ChannelId" + }, + "source": { + "$ref": "#/definitions/ChannelId" + } + } + }, "Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance": { "description": "Base XCVM instructions. This set will remain as small as possible, expressiveness must come on `top` of the base instructions.", "oneOf": [ @@ -939,22 +1037,6 @@ } } }, - "MessageHookMsg": { - "description": "This message should be send as part of wasm termination memo. So that can match it to sender hash and know what channel and origin was used to send message. All information here is not secured until compared with existing secured data.", - "type": "object", - "required": [ - "data", - "from_network_id" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "from_network_id": { - "$ref": "#/definitions/NetworkId" - } - } - }, "NetworkId": { "description": "Newtype for XCVM networks ID. Must be unique for each network and must never change. This ID is an opaque, arbitrary type from the XCVM protocol and no assumption must be made on how it is computed.", "type": "integer", @@ -964,20 +1046,21 @@ "NetworkItem": { "type": "object", "required": [ - "admin", - "id", - "interpreter_code_id" + "network_id" ], "properties": { - "admin": { - "description": "The admin which is allowed to update the bridge list.", - "allOf": [ + "accounts": { + "description": "Account encoding type", + "anyOf": [ { - "$ref": "#/definitions/Addr" + "$ref": "#/definitions/Prefix" + }, + { + "type": "null" } ] }, - "gateway_to_send_to": { + "gateway": { "description": "something which will be receiver on other side case of network has XCVM deployed as contract, account address is stored here", "anyOf": [ { @@ -998,25 +1081,8 @@ } ] }, - "id": { + "network_id": { "$ref": "#/definitions/NetworkId" - }, - "interpreter_code_id": { - "description": "Address of the XCVM interpreter contract code", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "prefix": { - "description": "Cosmos bech32 prefix per network, if there is prefix chain accounts are Cosmos SDK compatible chain", - "anyOf": [ - { - "$ref": "#/definitions/Prefix" - }, - { - "type": "null" - } - ] } } }, @@ -1034,11 +1100,10 @@ } ] }, - "ics_20_channel": { - "description": "channel to use to send ics 20 tokens", + "ics_20": { "anyOf": [ { - "$ref": "#/definitions/ChannelId" + "$ref": "#/definitions/IcsPair" }, { "type": "null" @@ -1260,6 +1325,22 @@ "type": "boolean" } } + }, + "XcMessageData": { + "description": "This message should be send as part of wasm termination memo. So that can match it to sender hash and know what channel and origin was used to send message. All information here is not secured until compared with existing secured data.", + "type": "object", + "required": [ + "data", + "from_network_id" + ], + "properties": { + "data": { + "$ref": "#/definitions/Binary" + }, + "from_network_id": { + "$ref": "#/definitions/NetworkId" + } + } } } } diff --git a/code/xcvm/lib/core/schema/raw/instantiate.json b/code/xcvm/lib/core/schema/raw/instantiate.json index 9eeadd4d936..75f93e86788 100644 --- a/code/xcvm/lib/core/schema/raw/instantiate.json +++ b/code/xcvm/lib/core/schema/raw/instantiate.json @@ -15,7 +15,7 @@ "type": "object", "required": [ "admin", - "id" + "here_id" ], "properties": { "admin": { @@ -26,7 +26,7 @@ } ] }, - "id": { + "here_id": { "description": "Network ID of this network", "allOf": [ { diff --git a/code/xcvm/lib/core/schema/raw/query.json b/code/xcvm/lib/core/schema/raw/query.json index 852574a5d4a..ac578079268 100644 --- a/code/xcvm/lib/core/schema/raw/query.json +++ b/code/xcvm/lib/core/schema/raw/query.json @@ -34,7 +34,7 @@ ] }, "Displayed_for_uint128": { - "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", + "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json_wasm::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json_wasm::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", "type": "integer", "format": "uint128", "minimum": 0.0 diff --git a/code/xcvm/lib/core/schema/raw/response_to_lookup_asset.json b/code/xcvm/lib/core/schema/raw/response_to_lookup_asset.json index f7e4e1a5042..5d4823edf73 100644 --- a/code/xcvm/lib/core/schema/raw/response_to_lookup_asset.json +++ b/code/xcvm/lib/core/schema/raw/response_to_lookup_asset.json @@ -26,11 +26,14 @@ "AssetItem": { "type": "object", "required": [ + "asset_id", "from_network_id", - "id", "local" ], "properties": { + "asset_id": { + "$ref": "#/definitions/AssetId" + }, "bridged": { "anyOf": [ { @@ -44,9 +47,6 @@ "from_network_id": { "$ref": "#/definitions/NetworkId" }, - "id": { - "$ref": "#/definitions/AssetId" - }, "local": { "$ref": "#/definitions/AssetReference" } @@ -78,16 +78,36 @@ { "type": "object", "required": [ - "virtual" + "a_d_r001" ], "properties": { - "virtual": { + "a_d_r001": { "type": "object", "required": [ - "cw20_address" + "sha256" ], "properties": { - "cw20_address": { + "sha256": { + "$ref": "#/definitions/HexBinary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { "$ref": "#/definitions/Addr" } } @@ -109,7 +129,7 @@ } }, "Displayed_for_uint128": { - "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", + "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json_wasm::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json_wasm::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", "type": "integer", "format": "uint128", "minimum": 0.0 @@ -119,10 +139,10 @@ { "type": "object", "required": [ - "IbcIcs20" + "ibc_ics20" ], "properties": { - "IbcIcs20": { + "ibc_ics20": { "$ref": "#/definitions/PrefixedDenom" } }, @@ -130,6 +150,10 @@ } ] }, + "HexBinary": { + "description": "This is a wrapper around Vec to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also .", + "type": "string" + }, "NetworkId": { "description": "Newtype for XCVM networks ID. Must be unique for each network and must never change. This ID is an opaque, arbitrary type from the XCVM protocol and no assumption must be made on how it is computed.", "type": "integer", diff --git a/code/xcvm/lib/core/schema/xc-core.json b/code/xcvm/lib/core/schema/xc-core.json index ea8ee7769c2..d9772db6cb9 100644 --- a/code/xcvm/lib/core/schema/xc-core.json +++ b/code/xcvm/lib/core/schema/xc-core.json @@ -19,7 +19,7 @@ "type": "object", "required": [ "admin", - "id" + "here_id" ], "properties": { "admin": { @@ -30,7 +30,7 @@ } ] }, - "id": { + "here_id": { "description": "Network ID of this network", "allOf": [ { @@ -167,7 +167,7 @@ ], "properties": { "message_hook": { - "$ref": "#/definitions/MessageHookMsg" + "$ref": "#/definitions/XcMessageData" } }, "additionalProperties": false @@ -205,11 +205,14 @@ "AssetItem": { "type": "object", "required": [ + "asset_id", "from_network_id", - "id", "local" ], "properties": { + "asset_id": { + "$ref": "#/definitions/AssetId" + }, "bridged": { "anyOf": [ { @@ -223,9 +226,6 @@ "from_network_id": { "$ref": "#/definitions/NetworkId" }, - "id": { - "$ref": "#/definitions/AssetId" - }, "local": { "$ref": "#/definitions/AssetReference" } @@ -257,16 +257,36 @@ { "type": "object", "required": [ - "virtual" + "a_d_r001" + ], + "properties": { + "a_d_r001": { + "type": "object", + "required": [ + "sha256" + ], + "properties": { + "sha256": { + "$ref": "#/definitions/HexBinary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" ], "properties": { - "virtual": { + "cw20": { "type": "object", "required": [ - "cw20_address" + "contract" ], "properties": { - "cw20_address": { + "contract": { "$ref": "#/definitions/Addr" } } @@ -473,33 +493,36 @@ } }, "ConfigSubMsg": { + "description": "cross cross chain routing requires a lot of configuration, about chain executing this contract, about connectivity to and of other chains (even if not connected directly) and about assets and services on these chains (in future block hooks and some set of host extensions/precompiles would help to get some info automatically) `Force` message sets the data unconditionally.", "oneOf": [ { + "description": "Permissioned message (gov or admin) to force set information about network contract is executed. Network can be any network or this network (so it overrides some this network parameters too)", "type": "object", "required": [ - "force_network_to_network" + "force_network" ], "properties": { - "force_network_to_network": { - "$ref": "#/definitions/ForceNetworkToNetworkMsg" + "force_network": { + "$ref": "#/definitions/NetworkItem" } }, "additionalProperties": false }, { + "description": "Sets network to network connectivity/routing information", "type": "object", "required": [ - "force_network" + "force_network_to_network" ], "properties": { - "force_network": { - "$ref": "#/definitions/NetworkItem" + "force_network_to_network": { + "$ref": "#/definitions/ForceNetworkToNetworkMsg" } }, "additionalProperties": false }, { - "description": "Message sent by an admin to register a new asset.", + "description": "Permissioned message (gov or admin) to force set asset information.", "type": "object", "required": [ "force_asset" @@ -560,7 +583,7 @@ ] }, "Displayed_for_uint128": { - "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", + "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json_wasm::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json_wasm::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", "type": "integer", "format": "uint128", "minimum": 0.0 @@ -630,10 +653,10 @@ { "type": "object", "required": [ - "IbcIcs20" + "ibc_ics20" ], "properties": { - "IbcIcs20": { + "ibc_ics20": { "$ref": "#/definitions/PrefixedDenom" } }, @@ -685,31 +708,63 @@ ], "properties": { "cosm_wasm": { - "$ref": "#/definitions/Addr" + "type": "object", + "required": [ + "admin", + "contract", + "interpreter_code_id" + ], + "properties": { + "admin": { + "description": "admin of everything", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "contract": { + "$ref": "#/definitions/Addr" + }, + "interpreter_code_id": { + "description": "Address of the XCVM interpreter contract code", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } } }, "additionalProperties": false } ] }, - "IbcEnabled": { + "HexBinary": { + "description": "This is a wrapper around Vec to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also .", + "type": "string" + }, + "IbcChannels": { "type": "object", "properties": { - "ics_20_features": { + "ics20": { "anyOf": [ { - "$ref": "#/definitions/Ics20Features" + "$ref": "#/definitions/Ics20Channel" }, { "type": "null" } ] - }, - "ics_20_sender": { - "description": "specific per chain way to send IBC ICS 20 assets", + } + } + }, + "IbcEnabled": { + "type": "object", + "properties": { + "channels": { "anyOf": [ { - "$ref": "#/definitions/IbcIcs20Sender" + "$ref": "#/definitions/IbcChannels" }, { "type": "null" @@ -738,8 +793,8 @@ { "type": "string", "enum": [ - "OsmosisModule", - "CosmWasmStd" + "CosmosStargateIbcApplicationsTransferV1MsgTransfer", + "CosmWasmStd1_3" ] }, { @@ -804,7 +859,34 @@ } } }, + "Ics20Channel": { + "type": "object", + "required": [ + "sender" + ], + "properties": { + "features": { + "anyOf": [ + { + "$ref": "#/definitions/Ics20Features" + }, + { + "type": "null" + } + ] + }, + "sender": { + "description": "specific per chain way to send IBC ICS 20 assets", + "allOf": [ + { + "$ref": "#/definitions/IbcIcs20Sender" + } + ] + } + } + }, "Ics20Features": { + "description": "what features/modules/version enabled/installed/configured", "type": "object", "properties": { "pfm": { @@ -830,6 +912,22 @@ } } }, + "IcsPair": { + "description": "we need both, so we can unwrap", + "type": "object", + "required": [ + "sink", + "source" + ], + "properties": { + "sink": { + "$ref": "#/definitions/ChannelId" + }, + "source": { + "$ref": "#/definitions/ChannelId" + } + } + }, "Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance": { "description": "Base XCVM instructions. This set will remain as small as possible, expressiveness must come on `top` of the base instructions.", "oneOf": [ @@ -989,22 +1087,6 @@ } } }, - "MessageHookMsg": { - "description": "This message should be send as part of wasm termination memo. So that can match it to sender hash and know what channel and origin was used to send message. All information here is not secured until compared with existing secured data.", - "type": "object", - "required": [ - "data", - "from_network_id" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "from_network_id": { - "$ref": "#/definitions/NetworkId" - } - } - }, "NetworkId": { "description": "Newtype for XCVM networks ID. Must be unique for each network and must never change. This ID is an opaque, arbitrary type from the XCVM protocol and no assumption must be made on how it is computed.", "type": "integer", @@ -1014,20 +1096,21 @@ "NetworkItem": { "type": "object", "required": [ - "admin", - "id", - "interpreter_code_id" + "network_id" ], "properties": { - "admin": { - "description": "The admin which is allowed to update the bridge list.", - "allOf": [ + "accounts": { + "description": "Account encoding type", + "anyOf": [ { - "$ref": "#/definitions/Addr" + "$ref": "#/definitions/Prefix" + }, + { + "type": "null" } ] }, - "gateway_to_send_to": { + "gateway": { "description": "something which will be receiver on other side case of network has XCVM deployed as contract, account address is stored here", "anyOf": [ { @@ -1048,25 +1131,8 @@ } ] }, - "id": { + "network_id": { "$ref": "#/definitions/NetworkId" - }, - "interpreter_code_id": { - "description": "Address of the XCVM interpreter contract code", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "prefix": { - "description": "Cosmos bech32 prefix per network, if there is prefix chain accounts are Cosmos SDK compatible chain", - "anyOf": [ - { - "$ref": "#/definitions/Prefix" - }, - { - "type": "null" - } - ] } } }, @@ -1084,11 +1150,10 @@ } ] }, - "ics_20_channel": { - "description": "channel to use to send ics 20 tokens", + "ics_20": { "anyOf": [ { - "$ref": "#/definitions/ChannelId" + "$ref": "#/definitions/IcsPair" }, { "type": "null" @@ -1310,6 +1375,22 @@ "type": "boolean" } } + }, + "XcMessageData": { + "description": "This message should be send as part of wasm termination memo. So that can match it to sender hash and know what channel and origin was used to send message. All information here is not secured until compared with existing secured data.", + "type": "object", + "required": [ + "data", + "from_network_id" + ], + "properties": { + "data": { + "$ref": "#/definitions/Binary" + }, + "from_network_id": { + "$ref": "#/definitions/NetworkId" + } + } } } }, @@ -1349,7 +1430,7 @@ ] }, "Displayed_for_uint128": { - "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", + "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json_wasm::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json_wasm::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", "type": "integer", "format": "uint128", "minimum": 0.0 @@ -1387,11 +1468,14 @@ "AssetItem": { "type": "object", "required": [ + "asset_id", "from_network_id", - "id", "local" ], "properties": { + "asset_id": { + "$ref": "#/definitions/AssetId" + }, "bridged": { "anyOf": [ { @@ -1405,9 +1489,6 @@ "from_network_id": { "$ref": "#/definitions/NetworkId" }, - "id": { - "$ref": "#/definitions/AssetId" - }, "local": { "$ref": "#/definitions/AssetReference" } @@ -1439,16 +1520,36 @@ { "type": "object", "required": [ - "virtual" + "a_d_r001" ], "properties": { - "virtual": { + "a_d_r001": { "type": "object", "required": [ - "cw20_address" + "sha256" ], "properties": { - "cw20_address": { + "sha256": { + "$ref": "#/definitions/HexBinary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { "$ref": "#/definitions/Addr" } } @@ -1470,7 +1571,7 @@ } }, "Displayed_for_uint128": { - "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", + "description": "A wrapper around a type which is serde-serialised as a string.\n\nFor serde-serialisation to be implemented for the type `T` must implement `Display` and `FromStr` traits.\n\n``` # use xc_core::Displayed;\n\n#[derive(serde::Serialize, serde::Deserialize)] struct Foo { value: Displayed }\n\nlet encoded = serde_json_wasm::to_string(&Foo { value: Displayed(42) }).unwrap(); assert_eq!(r#\"{\"value\":\"42\"}\"#, encoded);\n\nlet decoded = serde_json_wasm::from_str::(r#\"{\"value\":\"42\"}\"#).unwrap(); assert_eq!(Displayed(42), decoded.value); ```", "type": "integer", "format": "uint128", "minimum": 0.0 @@ -1480,10 +1581,10 @@ { "type": "object", "required": [ - "IbcIcs20" + "ibc_ics20" ], "properties": { - "IbcIcs20": { + "ibc_ics20": { "$ref": "#/definitions/PrefixedDenom" } }, @@ -1491,6 +1592,10 @@ } ] }, + "HexBinary": { + "description": "This is a wrapper around Vec to add hex de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is similar to `cosmwasm_std::Binary` but uses hex. See also .", + "type": "string" + }, "NetworkId": { "description": "Newtype for XCVM networks ID. Must be unique for each network and must never change. This ID is an opaque, arbitrary type from the XCVM protocol and no assumption must be made on how it is computed.", "type": "integer", diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index ac7c8f9578a..df78612e14a 100644 --- a/code/xcvm/lib/core/src/gateway/config.rs +++ b/code/xcvm/lib/core/src/gateway/config.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{IbcTimeout, HexBinary}; +use cosmwasm_std::IbcTimeout; use ibc_rs_scale::core::ics24_host::identifier::ChannelId; use crate::{ @@ -33,11 +33,27 @@ pub struct Ics20Features { } #[allow(clippy::large_enum_variant)] -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "snake_case")] -#[cfg_attr(feature = "std", derive(JsonSchema))] +#[cfg_attr(all(feature = "std",not(feature="substrate")), derive(JsonSchema))] pub enum ForeignAssetId { IbcIcs20(PrefixedDenom), + #[cfg(feature = "substrate")] + Xcm(xcm::VersionedMultiLocation) +} + +#[cfg(feature = "substrate")] +impl parity_scale_codec::MaxEncodedLen for ForeignAssetId { + fn max_encoded_len() -> usize { + 2048 + } +} + +#[cfg(feature = "substrate")] +impl From for ForeignAssetId { + fn from(this: xcm::VersionedMultiLocation) -> Self { + Self::Xcm(this) + } } impl From for ForeignAssetId { @@ -206,16 +222,16 @@ pub struct BridgeAsset { #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] pub enum AssetReference { Native { denom: String }, - ADR001 { sha256: HexBinary }, Cw20 { contract: Addr }, + // ADR001 { sha256: cosmwasm_std::HexBinary }, } impl AssetReference { pub fn denom(&self) -> String { match self { - AssetReference::ADR001 { sha256 } => ["ibc/", sha256].concat().to_owned(), + // AssetReference::ADR001 { sha256 } => ["ibc/", &sha256.to_string()].concat().to_string(), AssetReference::Native { denom } => denom.clone(), - AssetReference::Virtual { cw20_address } => ["cw20:", cw20_address.as_str()].concat(), + AssetReference::Cw20 { contract } => ["cw20:", contract.as_str()].concat(), } } } diff --git a/code/xcvm/lib/core/src/location.rs b/code/xcvm/lib/core/src/location.rs deleted file mode 100644 index d4e20ccc3ae..00000000000 --- a/code/xcvm/lib/core/src/location.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::prelude::*; -use ibc_rs_scale::applications::transfer::{BaseDenom, TracePath}; -use thiserror::Error; - -#[allow(clippy::large_enum_variant)] -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "std", derive(JsonSchema))] -pub enum ForeignAssetId { - IbcIcs20(PrefixedDenom), -} - -impl From for ForeignAssetId { - fn from(this: PrefixedDenom) -> Self { - Self::IbcIcs20(this) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "std", derive(schemars::JsonSchema))] -pub struct PrefixedDenom { - /// A series of `{port-id}/{channel-id}`s for tracing the source of the token. - pub trace_path: TracePath, - /// Base denomination of the relayed fungible token. - pub base_denom: BaseDenom, -} - -#[derive(Debug, Error)] -pub enum Error { - #[error("TokenTransferError")] - TokenTransferError, -} From 09c2d33046665b69e474610e6473803497f05f10 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 18:02:16 +0100 Subject: [PATCH 06/11] osmosis --- .../cosmwasm/contracts/gateway/src/assets.rs | 2 +- .../contracts/interpreter/src/contract.rs | 7 ++- code/xcvm/lib/core/src/asset.rs | 10 ++-- code/xcvm/lib/core/src/cosmos.rs | 9 ++-- code/xcvm/lib/core/src/gateway/config.rs | 7 +-- flake/osmosis.nix | 47 +++++++++++++++++++ 6 files changed, 63 insertions(+), 19 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs index 1c1f16bb9bc..3beaee4c90f 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs @@ -39,4 +39,4 @@ pub(crate) fn force_remove_asset( ASSETS.remove(deps.storage, asset_id); Ok(Response::new() .add_event(make_event("assets.removed").add_attribute("asset_id", asset_id.to_string()))) -} \ No newline at end of file +} diff --git a/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs b/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs index 397df98be74..c9cf07a9a55 100644 --- a/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs +++ b/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs @@ -324,12 +324,11 @@ pub fn interpret_spawn( to_address: gateway_address.clone().into(), amount: vec![Coin { denom, amount: transfer_amount.into() }], }), - AssetReference::Cw20 { contract } => response.add_message( - Cw20Contract(contract).call(Cw20ExecuteMsg::Transfer { + AssetReference::Cw20 { contract } => + response.add_message(Cw20Contract(contract).call(Cw20ExecuteMsg::Transfer { recipient: gateway_address.clone().into(), amount: transfer_amount.into(), - })?, - ), + })?), }; } } diff --git a/code/xcvm/lib/core/src/asset.rs b/code/xcvm/lib/core/src/asset.rs index 39a1aa30459..3430b9f7290 100644 --- a/code/xcvm/lib/core/src/asset.rs +++ b/code/xcvm/lib/core/src/asset.rs @@ -424,15 +424,15 @@ mod tests { let pica = generate_asset_id(0.into(), 0, 1); assert_eq!(pica, 1.into()); let pica = generate_asset_id(1.into(), 0, 1); - assert_eq!(pica, 79228162514264337593543950337.into()); + assert_eq!(pica, 79228162514264337593543950337.into()); let pica = generate_asset_id(2.into(), 0, 1); - assert_eq!(pica, 158456325028528675187087900673.into()); + assert_eq!(pica, 158456325028528675187087900673.into()); let pica = generate_asset_id(3.into(), 0, 1); - assert_eq!(pica, 237684487542793012780631851009.into()); + assert_eq!(pica, 237684487542793012780631851009.into()); let atom = generate_asset_id(2.into(), 0, 2); - assert_eq!(atom, 158456325028528675187087900674.into()); + assert_eq!(atom, 158456325028528675187087900674.into()); let atom = generate_asset_id(3.into(), 0, 2); - assert_eq!(atom, 237684487542793012780631851010.into()); + assert_eq!(atom, 237684487542793012780631851010.into()); } } diff --git a/code/xcvm/lib/core/src/cosmos.rs b/code/xcvm/lib/core/src/cosmos.rs index 4b869f1b419..8102464491e 100644 --- a/code/xcvm/lib/core/src/cosmos.rs +++ b/code/xcvm/lib/core/src/cosmos.rs @@ -35,20 +35,17 @@ mod tests { assert_eq!(pica, "ibc/B62D63F2BD5A7B70AB15F84BCB70EAC88222D3A8E8E0B22793EE788068EA22BA"); let pica = hash_denom_trace("/transfer/channel-0/1"); assert_eq!(pica, "ibc/F2B6EF5B6F86990A3863B78687ADE3D95E412657AAEB7CF2B3B8131B8055C1F1"); - + let pica: String = hash_denom_trace("/transfer/channel-1/ppica"); assert_eq!(pica, "ibc/661BD30059657725608DF36907F06B70C1FA7A1772FF92AEE1844A3E35A80D63"); let pica: String = hash_denom_trace("/transfer/channel-0/ppica"); assert_eq!(pica, "ibc/F0E228914E0E69E7B5E9231282FE6B7595CF90CB76E7193C6AFDCACDF5E83821"); - + let osmo: String = hash_denom_trace("/transfer/channel-1/uosmo"); assert_eq!(osmo, "ibc/BCACECE44E39A9009D793D68CC5DF76B402607B1C574379DCB4F3A5D24BC1936"); - + let osmo: String = hash_denom_trace("/transfer/channel-0/uosmo"); assert_eq!(osmo, "ibc/B4511F40A2844906F5940444691EE3AE877E8E0DD8354C8C4D36670A46C5680D"); - } } - - diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index df78612e14a..3a4d8030d61 100644 --- a/code/xcvm/lib/core/src/gateway/config.rs +++ b/code/xcvm/lib/core/src/gateway/config.rs @@ -35,11 +35,11 @@ pub struct Ics20Features { #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "snake_case")] -#[cfg_attr(all(feature = "std",not(feature="substrate")), derive(JsonSchema))] +#[cfg_attr(all(feature = "std", not(feature = "substrate")), derive(JsonSchema))] pub enum ForeignAssetId { IbcIcs20(PrefixedDenom), #[cfg(feature = "substrate")] - Xcm(xcm::VersionedMultiLocation) + Xcm(xcm::VersionedMultiLocation), } #[cfg(feature = "substrate")] @@ -229,7 +229,8 @@ pub enum AssetReference { impl AssetReference { pub fn denom(&self) -> String { match self { - // AssetReference::ADR001 { sha256 } => ["ibc/", &sha256.to_string()].concat().to_string(), + // AssetReference::ADR001 { sha256 } => ["ibc/", + // &sha256.to_string()].concat().to_string(), AssetReference::Native { denom } => denom.clone(), AssetReference::Cw20 { contract } => ["cw20:", contract.as_str()].concat(), } diff --git a/flake/osmosis.nix b/flake/osmosis.nix index 90c4f104957..a14635e547e 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -274,6 +274,53 @@ osmosisd tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$FORCE_CENTAURI_TO_OSMOSIS" --chain-id="$CHAIN_ID" --node "tcp://localhost:36657" --output json --yes --gas 25000000 --fees 920000166uosmo --log_level info --keyring-backend test --home "$OSMOSIS_DATA" --from validator --keyring-dir "$KEYRING_TEST" --trace --log_level trace + sleep $BLOCK_SECONDS + FORCE_PICA=$(cat << EOF + { + "config": { + "force_asset": { + "asset_id": "158456325028528675187087900673", + "from_network_id": 2, + "local": { + "native": { + "denom": "ppica" + } + }, + "bridged": { + "location_on_network": { + "ibc_ics20": { + "base_denom" : "ppica", + "trace_path" : "transfer/channel-0" + } + } + } + } + } + } + EOF + ) + osmosisd tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$FORCE_PICA" --chain-id="$CHAIN_ID" --node "tcp://localhost:36657" --output json --yes --gas 25000000 --fees 920000166uosmo --log_level info --keyring-backend test --home "$OSMOSIS_DATA" --from validator --keyring-dir "$KEYRING_TEST" --trace --log_level trace + + + sleep $BLOCK_SECONDS + FORCE_UATOM=$(cat << EOF + { + "config": { + "force_asset": { + "asset_id": "237684487542793012780631851010", + "from_network_id": 3, + "local": { + "native": { + "denom" : "uatom" + } + } + } + } + } + EOF + ) + osmosisd tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$FORCE_UATOM" --chain-id="$CHAIN_ID" --node "tcp://localhost:36657" --output json --yes --gas 25000000 --fees 920000166uosmo --log_level info --keyring-backend test --home "$OSMOSIS_DATA" --from validator --keyring-dir "$KEYRING_TEST" --trace --log_level trace + sleep $BLOCK_SECONDS osmosisd query wasm contract-state all "$GATEWAY_CONTRACT_ADDRESS" --chain-id="$CHAIN_ID" --node "tcp://localhost:36657" --output json --home "$OSMOSIS_DATA" ''; From b4b2ca02c91c0d699bf73ffc3aa9bbeaa8262e27 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 18:23:23 +0100 Subject: [PATCH 07/11] Update code/xcvm/cosmwasm/contracts/gateway/README.md Co-authored-by: Michal Nazarewicz Signed-off-by: dzmitry-lahoda --- code/xcvm/cosmwasm/contracts/gateway/README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/README.md b/code/xcvm/cosmwasm/contracts/gateway/README.md index 1c9945f4493..a95b1aa5cc6 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/README.md +++ b/code/xcvm/cosmwasm/contracts/gateway/README.md @@ -6,7 +6,4 @@ Hides custom entry points and messaging under unified security, routing, assets Is Entrypoint and exit for Programs. Also handles interactions with [OTP](otp.md). -Book keeps per-chain state. Holds the address mappings for cross-chain accounts and instantiates new interpreters. - - -## Handling cases when there is no contract \ No newline at end of file +Book keeps per-chain state. Holds the address mappings for cross-chain accounts and instantiates new interpreters. \ No newline at end of file From 92db4b883ff8d324126cee96187c7d99c92f2e30 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 18:23:40 +0100 Subject: [PATCH 08/11] Update code/xcvm/lib/core/src/asset.rs Co-authored-by: Michal Nazarewicz Signed-off-by: dzmitry-lahoda --- code/xcvm/lib/core/src/asset.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/code/xcvm/lib/core/src/asset.rs b/code/xcvm/lib/core/src/asset.rs index 3430b9f7290..6c0c0719f7a 100644 --- a/code/xcvm/lib/core/src/asset.rs +++ b/code/xcvm/lib/core/src/asset.rs @@ -404,16 +404,9 @@ impl From> for Vec<(u128, T)> { } pub fn generate_asset_id(network_id: NetworkId, protocol_id: u32, nonce: u64) -> AssetId { - [ - network_id.0.to_be_bytes().to_vec(), - protocol_id.to_be_bytes().to_vec(), - nonce.to_be_bytes().to_vec(), - ] - .concat() - .try_into() - .map(u128::from_be_bytes) - .expect("[u8; 8] + bytes(u64) = [u8; 16]") - .into() + AssetId::from((u128::from(network_id) << 96) | + (u128::from(protocol_id) << 64) | + (u128::from(nonce)) } #[cfg(test)] From 5712321f4cc419d254477e7b4124867371dd0a03 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 18:25:01 +0100 Subject: [PATCH 09/11] fix --- code/xcvm/lib/core/src/asset.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/xcvm/lib/core/src/asset.rs b/code/xcvm/lib/core/src/asset.rs index 6c0c0719f7a..01c1eb5aa1a 100644 --- a/code/xcvm/lib/core/src/asset.rs +++ b/code/xcvm/lib/core/src/asset.rs @@ -404,9 +404,9 @@ impl From> for Vec<(u128, T)> { } pub fn generate_asset_id(network_id: NetworkId, protocol_id: u32, nonce: u64) -> AssetId { - AssetId::from((u128::from(network_id) << 96) | - (u128::from(protocol_id) << 64) | - (u128::from(nonce)) + AssetId::from( + (u128::from(network_id.0) << 96) | (u128::from(protocol_id) << 64) | (u128::from(nonce)), + ) } #[cfg(test)] From 45631eea8e4aa007d9219408313c580e7df69017 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 18:28:23 +0100 Subject: [PATCH 10/11] fixed --- code/xcvm/lib/core/src/asset.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/xcvm/lib/core/src/asset.rs b/code/xcvm/lib/core/src/asset.rs index 01c1eb5aa1a..9fe37a69bdc 100644 --- a/code/xcvm/lib/core/src/asset.rs +++ b/code/xcvm/lib/core/src/asset.rs @@ -403,6 +403,9 @@ impl From> for Vec<(u128, T)> { } } +// `protocol_id` - namespace like thing, default is 0, but can be used for example other consensus +// to create known ahead +/// `nonce` - local consensus atomic number, usually increasing monotonic increment pub fn generate_asset_id(network_id: NetworkId, protocol_id: u32, nonce: u64) -> AssetId { AssetId::from( (u128::from(network_id.0) << 96) | (u128::from(protocol_id) << 64) | (u128::from(nonce)), From f3174c945c379bf9a199e898f8f5a41c5a1eddca Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Thu, 3 Aug 2023 18:49:15 +0100 Subject: [PATCH 11/11] fixed tests --- code/xcvm/cosmwasm/tests/src/tests/framework.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/xcvm/cosmwasm/tests/src/tests/framework.rs b/code/xcvm/cosmwasm/tests/src/tests/framework.rs index bad8e47a259..53115ce1610 100644 --- a/code/xcvm/cosmwasm/tests/src/tests/framework.rs +++ b/code/xcvm/cosmwasm/tests/src/tests/framework.rs @@ -276,8 +276,8 @@ impl TestVM> { (ConfigSubMsg::ForceAsset(AssetItem { asset_id, from_network_id: todo!("restore"), - local: xc_core::gateway::AssetReference::Virtual { - cw20_address: asset_address.clone().into(), + local: xc_core::gateway::AssetReference::Cw20 { + contract: asset_address.clone().into(), }, bridged: None, })),