From debc6bcba0bac08c9aea5f151bc526cc600342b1 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Fri, 11 Aug 2023 15:42:20 +0100 Subject: [PATCH 01/17] feat(cw-ibc): finally transfer --- flake/osmosis.nix | 56 ++++++++++++++++++++++++++++++++++++++- flake/process-compose.nix | 8 +++--- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/flake/osmosis.nix b/flake/osmosis.nix index badc1affb92..f28f9a768fc 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -147,7 +147,61 @@ ''; }; - osmosisd-init = pkgs.writeShellApplication { + osmosisd-xcvm-init = pkgs.writeShellApplication { + name = "osmosisd-init"; + runtimeInputs = devnetTools.withBaseContainerTools + ++ [ osmosisd pkgs.jq pkgs.dasel ]; + text = '' + HOME=/tmp/composable-devnet + export HOME + CHAIN_DATA="$HOME/.osmosisd" + KEYRING_TEST=$CHAIN_DATA + CHAIN_ID="osmosis-dev" + PORT=36657 + BLOCK_SECONDS=5 + FEE=uosmo + NETWORK_ID=3 + KEY=${cosmosTools.xcvm.osmosis} + BINARY=osmosisd + + function init_xcvm() { + local INSTANTIATE=$1 + echo $NETWORK_ID + "$BINARY" tx wasm store "${self'.packages.xc-cw-contracts}/lib/cw_xc_gateway.wasm" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" + GATEWAY_CODE_ID=1 + + sleep $BLOCK_SECONDS + "$BINARY" tx wasm store "${self'.packages.xc-cw-contracts}/lib/cw_xc_interpreter.wasm" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" + INTERPRETER_CODE_ID=2 + + sleep $BLOCK_SECONDS + "$BINARY" tx wasm store "${self'.packages.cw20_base}" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" + + sleep $BLOCK_SECONDS + + "$BINARY" tx wasm instantiate2 $GATEWAY_CODE_ID "$INSTANTIATE" "1234" --label "xc-gateway" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" --admin "$KEY" + + sleep $BLOCK_SECONDS + GATEWAY_CONTRACT_ADDRESS=$("$BINARY" query wasm list-contract-by-code "$GATEWAY_CODE_ID" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --home "$CHAIN_DATA" | dasel --read json '.contracts.[0]' --write yaml) + echo "$GATEWAY_CONTRACT_ADDRESS" > "$CHAIN_DATA/gateway_contract_address" + echo "$INTERPRETER_CODE_ID" > "$CHAIN_DATA/interpreter_code_id" + } + + INSTANTIATE=$(cat << EOF + { + "admin" : "$KEY", + "here_id" : $NETWORK_ID + } + EOF + ) + + init_xcvm "$INSTANTIATE" + ''; + }; + + + + osmosisd-xcvm-config = pkgs.writeShellApplication { name = "osmosisd-init"; runtimeInputs = devnetTools.withBaseContainerTools ++ [ osmosisd pkgs.jq pkgs.dasel ]; diff --git a/flake/process-compose.nix b/flake/process-compose.nix index 25d0f514ae1..ead02162c19 100644 --- a/flake/process-compose.nix +++ b/flake/process-compose.nix @@ -256,10 +256,10 @@ }; log_location = "/tmp/composable-devnet/osmosis.log"; }; - osmosis-init = { + osmosisd-xcvm-init = { command = self'.packages.osmosisd-init; depends_on."osmosis".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/osmosis-init.log"; + log_location = "/tmp/composable-devnet/osmosisd-xcvm-init.log"; availability = { restart = "on_failure"; }; }; @@ -463,10 +463,10 @@ }; log_location = "/tmp/composable-devnet/osmosis.log"; }; - osmosis-init = { + osmosisd-xcvm-init = { command = self'.packages.osmosisd-init; depends_on."osmosis".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/osmosis-init.log"; + log_location = "/tmp/composable-devnet/osmosisd-xcvm-init.log"; availability = { restart = "on_failure"; }; }; From 4046977fd291db38a95d557cfd10cc7fdc97d8a3 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Fri, 11 Aug 2023 15:46:16 +0100 Subject: [PATCH 02/17] osmosis like centauri --- flake/process-compose.nix | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/flake/process-compose.nix b/flake/process-compose.nix index ead02162c19..b4031d00a25 100644 --- a/flake/process-compose.nix +++ b/flake/process-compose.nix @@ -450,11 +450,24 @@ command = self'.packages.centaurid-xcvm-config; depends_on."centauri-xcvm-init".condition = "process_completed_successfully"; + depends_on."osmosis-xcvm-init".condition = + "process_completed_successfully"; log_location = "/tmp/composable-devnet/centauri-xcvm-config.log"; availability = { restart = "on_failure"; }; }; + osmosis-xcvm-config = { + command = self'.packages.centaurid-xcvm-config; + depends_on."centauri-xcvm-init".condition = + "process_completed_successfully"; + depends_on."osmosis-xcvm-init".condition = + "process_completed_successfully"; + log_location = + "/tmp/composable-devnet/osmosis-xcvm-config.log"; + availability = { restart = "on_failure"; }; + }; + osmosis = { command = self'.packages.osmosisd-gen; readiness_probe.http_get = { From 430d4eefebfaf7967dd64e38c4944708a3b49cd2 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Fri, 11 Aug 2023 16:11:43 +0100 Subject: [PATCH 03/17] proper config for osmo --- flake/osmosis.nix | 41 +++++---------------------------------- flake/process-compose.nix | 15 +++++++------- 2 files changed, 12 insertions(+), 44 deletions(-) diff --git a/flake/osmosis.nix b/flake/osmosis.nix index f28f9a768fc..f3c122ce066 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -148,7 +148,7 @@ }; osmosisd-xcvm-init = pkgs.writeShellApplication { - name = "osmosisd-init"; + name = "osmosisd-xcvm-init"; runtimeInputs = devnetTools.withBaseContainerTools ++ [ osmosisd pkgs.jq pkgs.dasel ]; text = '' @@ -199,10 +199,8 @@ ''; }; - - osmosisd-xcvm-config = pkgs.writeShellApplication { - name = "osmosisd-init"; + name = "osmosisd-xcvm-config"; runtimeInputs = devnetTools.withBaseContainerTools ++ [ osmosisd pkgs.jq pkgs.dasel ]; text = '' @@ -218,43 +216,14 @@ KEY=${cosmosTools.xcvm.osmosis} BINARY=osmosisd - function init_xcvm() { - local INSTANTIATE=$1 - echo $NETWORK_ID - "$BINARY" tx wasm store "${self'.packages.xc-cw-contracts}/lib/cw_xc_gateway.wasm" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" - GATEWAY_CODE_ID=1 - - sleep $BLOCK_SECONDS - "$BINARY" tx wasm store "${self'.packages.xc-cw-contracts}/lib/cw_xc_interpreter.wasm" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" - INTERPRETER_CODE_ID=2 - - sleep $BLOCK_SECONDS - "$BINARY" tx wasm store "${self'.packages.cw20_base}" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" - - sleep $BLOCK_SECONDS - - "$BINARY" tx wasm instantiate2 $GATEWAY_CODE_ID "$INSTANTIATE" "1234" --label "xc-gateway" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" --admin "$KEY" - - sleep $BLOCK_SECONDS - GATEWAY_CONTRACT_ADDRESS=$("$BINARY" query wasm list-contract-by-code "$GATEWAY_CODE_ID" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --home "$CHAIN_DATA" | dasel --read json '.contracts.[0]' --write yaml) - echo "$GATEWAY_CONTRACT_ADDRESS" > "$CHAIN_DATA/gateway_contract_address" - } - - INSTANTIATE=$(cat << EOF - { - "admin" : "$KEY", - "here_id" : $NETWORK_ID - } - EOF - ) - - init_xcvm "$INSTANTIATE" + GATEWAY_CONTRACT_ADDRESS=$(cat $CHAIN_DATA/gateway_contract_address) + INTERPRETER_CODE_ID=$(cat $CHAIN_DATA/interpreter_code_id) FORCE_NETWORK_OSMOSIS=$(cat << EOF { "config": { "force_network": { - "network_id": 3, + "network_id": $NETWORK_ID, "accounts": { "bech": "osmo" }, diff --git a/flake/process-compose.nix b/flake/process-compose.nix index b4031d00a25..0769a57ee1d 100644 --- a/flake/process-compose.nix +++ b/flake/process-compose.nix @@ -257,7 +257,7 @@ log_location = "/tmp/composable-devnet/osmosis.log"; }; osmosisd-xcvm-init = { - command = self'.packages.osmosisd-init; + command = self'.packages.osmosisd-xcvm-init; depends_on."osmosis".condition = "process_healthy"; log_location = "/tmp/composable-devnet/osmosisd-xcvm-init.log"; availability = { restart = "on_failure"; }; @@ -451,22 +451,21 @@ depends_on."centauri-xcvm-init".condition = "process_completed_successfully"; depends_on."osmosis-xcvm-init".condition = - "process_completed_successfully"; + "process_completed_successfully"; log_location = "/tmp/composable-devnet/centauri-xcvm-config.log"; availability = { restart = "on_failure"; }; }; osmosis-xcvm-config = { - command = self'.packages.centaurid-xcvm-config; + command = self'.packages.osmosis-xcvm-config; depends_on."centauri-xcvm-init".condition = "process_completed_successfully"; depends_on."osmosis-xcvm-init".condition = - "process_completed_successfully"; - log_location = - "/tmp/composable-devnet/osmosis-xcvm-config.log"; + "process_completed_successfully"; + log_location = "/tmp/composable-devnet/osmosis-xcvm-config.log"; availability = { restart = "on_failure"; }; - }; + }; osmosis = { command = self'.packages.osmosisd-gen; @@ -477,7 +476,7 @@ log_location = "/tmp/composable-devnet/osmosis.log"; }; osmosisd-xcvm-init = { - command = self'.packages.osmosisd-init; + command = self'.packages.osmosisd-xcvm-init; depends_on."osmosis".condition = "process_healthy"; log_location = "/tmp/composable-devnet/osmosisd-xcvm-init.log"; availability = { restart = "on_failure"; }; From 3cfe60cfc9b7234c8b924e1cf7d67e4c86962e10 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Fri, 11 Aug 2023 16:39:53 +0100 Subject: [PATCH 04/17] fixed counterparty --- flake/osmosis.nix | 5 ++-- flake/process-compose.nix | 7 +++--- .../composable-centauri/flake-module.nix | 25 +++++++++++++------ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/flake/osmosis.nix b/flake/osmosis.nix index f3c122ce066..93931553e4a 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -217,6 +217,7 @@ BINARY=osmosisd GATEWAY_CONTRACT_ADDRESS=$(cat $CHAIN_DATA/gateway_contract_address) + CENTAURI_GATEWAY_CONTRACT_ADDRESS=$(cat "$HOME/.centaurid/gateway_contract_address") INTERPRETER_CODE_ID=$(cat $CHAIN_DATA/interpreter_code_id) FORCE_NETWORK_OSMOSIS=$(cat << EOF @@ -265,7 +266,7 @@ }, "gateway": { "cosm_wasm": { - "contract": "$GATEWAY_CONTRACT_ADDRESS", + "contract": "$CENTAURI_GATEWAY_CONTRACT_ADDRESS", "interpreter_code_id": $INTERPRETER_CODE_ID, "admin": "$KEY" } @@ -300,7 +301,7 @@ "to": 3, "other": { "counterparty_timeout": { - "timestamp": "60" + "timestamp": 60000000000 }, "ics_20": { "source" : "channel-0", diff --git a/flake/process-compose.nix b/flake/process-compose.nix index 0769a57ee1d..fb37ebebe16 100644 --- a/flake/process-compose.nix +++ b/flake/process-compose.nix @@ -445,6 +445,7 @@ log_location = "/tmp/composable-devnet/centauri-xcvm-init.log"; availability = { restart = "on_failure"; }; }; + centauri-xcvm-config = { command = self'.packages.centaurid-xcvm-config; @@ -458,7 +459,7 @@ }; osmosis-xcvm-config = { - command = self'.packages.osmosis-xcvm-config; + command = self'.packages.osmosisd-xcvm-config; depends_on."centauri-xcvm-init".condition = "process_completed_successfully"; depends_on."osmosis-xcvm-init".condition = @@ -475,10 +476,10 @@ }; log_location = "/tmp/composable-devnet/osmosis.log"; }; - osmosisd-xcvm-init = { + osmosis-xcvm-init = { command = self'.packages.osmosisd-xcvm-init; depends_on."osmosis".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/osmosisd-xcvm-init.log"; + log_location = "/tmp/composable-devnet/osmosis-xcvm-init.log"; availability = { restart = "on_failure"; }; }; diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index cd2ce27cc0e..792cf2d6b02 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -129,17 +129,22 @@ ++ [ centaurid pkgs.jq self'.packages.xc-cw-contracts ]; text = '' - CHAIN_DATA="${devnet-root-directory}/.centaurid" + HOME=${devnet-root-directory} + export HOME + KEY=${cosmosTools.xcvm.centauri} + + CHAIN_DATA="$HOME/.centaurid" CHAIN_ID="centauri-dev" KEYRING_TEST="$CHAIN_DATA/keyring-test" - KEY=${cosmosTools.xcvm.centauri} PORT=26657 BLOCK_SECONDS=5 FEE=ppica BINARY=centaurid + GATEWAY_CONTRACT_ADDRESS=$(cat $CHAIN_DATA/gateway_contract_address) INTERPRETER_CODE_ID=$(cat $CHAIN_DATA/interpreter_code_id) + OSMOSIS_GATEWAY_CONTRACT_ADDRESS=$(cat "$HOME/.osmosisd/gateway_contract_address") FORCE_NETWORK_OSMOSIS=$(cat << EOF { @@ -151,7 +156,7 @@ }, "gateway": { "cosm_wasm": { - "contract": "$GATEWAY_CONTRACT_ADDRESS", + "contract": "$OSMOSIS_GATEWAY_CONTRACT_ADDRESS", "interpreter_code_id": $INTERPRETER_CODE_ID, "admin": "$KEY" } @@ -222,7 +227,7 @@ "to": 3, "other": { "counterparty_timeout": { - "timestamp": "60" + "timestamp": 60000000000 }, "ics_20": { "source" : "channel-0", @@ -462,10 +467,14 @@ jq-genesis '.app_state.gov.params.voting_period |= "${gov.voting_period}"' jq-genesis '.app_state.gov.params.max_deposit_period |= "${gov.max_deposit_period}"' - jq-genesis '.app_state.transmiddleware.token_infos[0].ibc_denom |= "ibc/632DBFDB06584976F1351A66E873BF0F7A19FAA083425FEC9890C90993E5F0A4"' - jq-genesis '.app_state.transmiddleware.token_infos[0].channel_id |= "channel-0"' - jq-genesis '.app_state.transmiddleware.token_infos[0].native_denom |= "ppica"' - jq-genesis '.app_state.transmiddleware.token_infos[0].asset_id |= "1"' + function pica() { + jq-genesis '.app_state.transmiddleware.token_infos[0].ibc_denom |= "ibc/632DBFDB06584976F1351A66E873BF0F7A19FAA083425FEC9890C90993E5F0A4"' + jq-genesis '.app_state.transmiddleware.token_infos[0].channel_id |= "channel-0"' + jq-genesis '.app_state.transmiddleware.token_infos[0].native_denom |= "ppica"' + jq-genesis '.app_state.transmiddleware.token_infos[0].asset_id |= "1"' + } + # disabled until https://github.com/notional-labs/composable-centauri/issues/219 + # pica sed -i 's/keyring-backend = "os"/keyring-backend = "test"/' "$CHAIN_DATA/config/client.toml" sed -i 's/keyring-backend = "os"/keyring-backend = "test"/' "$CHAIN_DATA/config/client.toml" From 64e76b045ef23aee4af96a84c8c9fa03b3c2da36 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Fri, 11 Aug 2023 18:33:25 +0100 Subject: [PATCH 05/17] issues --- flake/hermes.nix | 5 +++-- flake/osmosis.nix | 2 +- flake/process-compose.nix | 1 - .../composable-centauri/flake-module.nix | 19 +++++++++++++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/flake/hermes.nix b/flake/hermes.nix index 3af4d514a75..9cce98c4220 100644 --- a/flake/hermes.nix +++ b/flake/hermes.nix @@ -4,6 +4,7 @@ let devnet-root-directory = "/tmp/composable-devnet"; validator-key = "osmo12smx2wdlyttvyzvzg54y2vnqwq2qjateuf7thj"; + log = "debug"; in { packages = rec { hermes = self.inputs.cosmos.packages.${system}.hermes; @@ -11,6 +12,7 @@ runtimeInputs = devnetTools.withBaseContainerTools ++ [ hermes ]; name = "osmosis-centauri-hermes-init"; text = '' + RUST_LOG=${log} mkdir --parents "${devnet-root-directory}" HOME=${devnet-root-directory} export HOME @@ -24,7 +26,6 @@ echo "black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken" > "$MNEMONIC_FILE" hermes keys add --chain centauri-dev --mnemonic-file "$MNEMONIC_FILE" --key-name centauri-dev --overwrite hermes keys add --chain osmosis-dev --mnemonic-file "$MNEMONIC_FILE" --key-name osmosis-dev --overwrite - RUST_LOG=info export RUST_LOG hermes create channel --a-chain centauri-dev --b-chain osmosis-dev --a-port transfer --b-port transfer --new-client-connection --yes ''; @@ -33,10 +34,10 @@ runtimeInputs = devnetTools.withBaseContainerTools ++ [ hermes ]; name = "osmosis-centauri-hermes-relay"; text = '' + RUST_LOG=${log} mkdir --parents "${devnet-root-directory}" HOME=${devnet-root-directory} export HOME - RUST_LOG=info export RUST_LOG hermes start ''; diff --git a/flake/osmosis.nix b/flake/osmosis.nix index 93931553e4a..1fc5b872c20 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -301,7 +301,7 @@ "to": 3, "other": { "counterparty_timeout": { - "timestamp": 60000000000 + "timestamp": "30000000000" }, "ics_20": { "source" : "channel-0", diff --git a/flake/process-compose.nix b/flake/process-compose.nix index fb37ebebe16..7f1726f66bb 100644 --- a/flake/process-compose.nix +++ b/flake/process-compose.nix @@ -445,7 +445,6 @@ log_location = "/tmp/composable-devnet/centauri-xcvm-init.log"; availability = { restart = "on_failure"; }; }; - centauri-xcvm-config = { command = self'.packages.centaurid-xcvm-config; diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index 792cf2d6b02..c6e24d04e08 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -133,7 +133,7 @@ HOME=${devnet-root-directory} export HOME KEY=${cosmosTools.xcvm.centauri} - + CHAIN_DATA="$HOME/.centaurid" CHAIN_ID="centauri-dev" KEYRING_TEST="$CHAIN_DATA/keyring-test" @@ -227,7 +227,7 @@ "to": 3, "other": { "counterparty_timeout": { - "timestamp": 60000000000 + "timestamp": "30000000000" }, "ics_20": { "source" : "channel-0", @@ -539,6 +539,21 @@ "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$MSG" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace ''; }; + centauri-tx = pkgs.writeShellApplication { + name = "centaurid-xcvm-config"; + runtimeInputs = devnetTools.withBaseContainerTools + ++ [ centaurid pkgs.jq self'.packages.xc-cw-contracts ]; + + text = '' + CHAIN_DATA="${devnet-root-directory}/.centaurid" + CHAIN_ID="centauri-dev" + KEYRING_TEST="$CHAIN_DATA/keyring-test" + PORT=26657 + FEE=ppica + BINARY=centaurid + "$BINARY" tx ibc-transfer transfer transfer channel-0 osmo12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n 10000000000ppica --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace + ''; + }; }; }; } From d69fe6b33d8c46cbe23d78d40a28e5d078b05046 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Fri, 11 Aug 2023 20:57:54 +0100 Subject: [PATCH 06/17] better timeout --- .../contracts/gateway/src/contract/execute.rs | 2 +- .../gateway/src/contract/ibc/ics20.rs | 2 +- .../cosmwasm/contracts/gateway/src/prelude.rs | 1 + code/xcvm/lib/core/src/prelude.rs | 1 + .../lib/core/src/transport/ibc/ics20/hook.rs | 2 +- .../lib/core/src/transport/ibc/ics20/mod.rs | 1 + code/xcvm/lib/core/src/transport/ibc/mod.rs | 13 +++++----- flake/hermes.toml | 6 ++--- flake/osmosis.nix | 25 ++++++++++++++----- .../composable-centauri/flake-module.nix | 5 +++- 10 files changed, 39 insertions(+), 19 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index 2b533bd1d13..af9e29f158e 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -43,7 +43,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) } }, msg::ExecuteMsg::MessageHook(msg) => { - deps.api.debug(&serde_json_wasm::to_string(&msg)?); + deps.api.debug(format!("xcvm::gateway::execute::message_hook {:?}", msg).as_str()); let auth = auth::WasmHook::authorise(deps.storage, &env, &info, msg.from_network_id)?; super::ibc::ics20::ics20_message_hook(auth, msg, env, info) }, diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index c7ce7ffe7da..3b25a0d26ef 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -71,7 +71,7 @@ pub(crate) fn handle_bridge_forward( let coin = Coin::new(amount.0, route.local_native_denom.clone()); - let msg = to_cw_message(coin, route, packet)?; + let msg = to_cw_message(deps.api, coin, route, packet)?; deps.api.debug(&format!( "xcvm::gateway::ibc::ics20:: payload {}", &serde_json_wasm::to_string(&msg)? diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs b/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs index e5b28664513..af3c5437c5c 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs @@ -3,3 +3,4 @@ pub use cw_storage_plus::Map; pub use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId}; pub use serde::{Deserialize, Serialize}; pub use xc_core::gateway::config::*; +pub use alloc::format; \ No newline at end of file diff --git a/code/xcvm/lib/core/src/prelude.rs b/code/xcvm/lib/core/src/prelude.rs index ddcc9b75d49..766b59bc4f1 100644 --- a/code/xcvm/lib/core/src/prelude.rs +++ b/code/xcvm/lib/core/src/prelude.rs @@ -4,6 +4,7 @@ pub use alloc::{ string::{String, ToString}, vec, vec::Vec, + format, }; pub use core::{fmt::Display, str::FromStr}; pub use cosmwasm_std::{Addr, Binary, Coin, HexBinary, Uint128}; diff --git a/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs b/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs index 0677d8290d7..d9cbe65ae67 100644 --- a/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs +++ b/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs @@ -50,6 +50,6 @@ pub struct Callback { // really Addr, but it does not have scale, I guess we need to impl `type XcAddr = SS58 | // Bech32` with signer inside for serde pub contract: Addr, - /// really serde_cw_value::Value, but it has not scale + /// Is a valid JSON object. The contract will be called with this as the message. pub msg: serde_cw_value::Value, } diff --git a/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs b/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs index 13549fb76ca..f08499b2483 100644 --- a/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs @@ -12,6 +12,7 @@ use self::{hook::Callback, pfm::ForwardingMemo}; #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] // Encode, Decode, scale_info::TypeInfo, to be manually implemented for subset of know messages pub struct Memo { + /// memo has at least one key, with value "wasm", than wasm hooks will try to execute it #[serde(skip_serializing_if = "Option::is_none")] pub wasm: Option, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/code/xcvm/lib/core/src/transport/ibc/mod.rs b/code/xcvm/lib/core/src/transport/ibc/mod.rs index 4a887f6198d..8b99a95d744 100644 --- a/code/xcvm/lib/core/src/transport/ibc/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/mod.rs @@ -1,8 +1,8 @@ pub mod ics20; pub mod picasso; -use crate::{prelude::*, shared::XcPacket, AssetId, NetworkId}; -use cosmwasm_std::{to_binary, CosmosMsg, IbcEndpoint, IbcTimeout, StdResult, WasmMsg}; +use crate::{prelude::*, shared::XcPacket, AssetId, NetworkId, gateway}; +use cosmwasm_std::{to_binary, CosmosMsg, IbcEndpoint, IbcTimeout, StdResult, WasmMsg, Api}; use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; @@ -47,23 +47,24 @@ pub struct IbcIcs20Route { } pub fn to_cw_message( + api: &dyn Api, coin: Coin, route: IbcIcs20Route, packet: XcPacket, ) -> StdResult> { - let memo = XcMessageData { from_network_id: route.from_network, packet }; + let msg = gateway::ExecuteMsg::MessageHook(XcMessageData { from_network_id: route.from_network, packet }); let memo = SendMemo { inner: Memo { wasm: Some(Callback { contract: route.gateway_to_send_to.clone(), - msg: serde_cw_value::to_value(memo).expect("can always serde"), + msg: serde_cw_value::to_value(msg).expect("can always serde"), }), forward: None, }, ibc_callback: None, }; let memo = serde_json_wasm::to_string(&memo).expect("any memo can be to string"); - + api.debug(&format!("xcvm::ibc::ics20 callback {}", &memo)); match route.ibc_ics_20_sender { IbcIcs20Sender::SubstratePrecompile(addr) => { let transfer = picasso::IbcMsg::Transfer { @@ -106,7 +107,7 @@ pub fn to_cw_message( .timestamp() .map(|x| x.seconds()) .unwrap_or_default(), - memo, + memo : "".into(), } .encode_to_vec(); let value = Binary::from(value); diff --git a/flake/hermes.toml b/flake/hermes.toml index b05995ca74b..9fc9f9d3c70 100644 --- a/flake/hermes.toml +++ b/flake/hermes.toml @@ -35,7 +35,7 @@ rpc_timeout = '20s' account_prefix = 'centauri' key_name = 'centauri-dev' store_prefix = 'ibc' -default_gas = 1000000 +default_gas = 10000000 max_gas = 400000000 gas_price = { price = 0.001, denom = 'ppica' } gas_multiplier = 1.1 @@ -59,8 +59,8 @@ account_prefix = 'osmo' key_name = 'osmosis-dev' store_prefix = 'ibc' key_store_type = 'Test' -default_gas = 100000 -max_gas = 400000 +default_gas = 10000000 +max_gas = 400000000 gas_price = { price = 0.01, denom = 'uosmo' } gas_multiplier = 1.1 max_msg_num = 30 diff --git a/flake/osmosis.nix b/flake/osmosis.nix index 1fc5b872c20..e212697fc78 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -1,10 +1,20 @@ { self, ... }: { - perSystem = { self', pkgs, systemCommonRust, subnix, lib, system, devnetTools - , cosmosTools, ... }: + perSystem = + { self' + , pkgs + , systemCommonRust + , subnix + , lib + , system + , devnetTools + , cosmosTools + , ... + }: let devnet-root-directory = cosmosTools.devnet-root-directory; validator-key = cosmosTools.validators.osmosis; - in { + in + { packages = rec { osmosisd = pkgs.writeShellApplication { name = "osmosisd"; @@ -301,7 +311,10 @@ "to": 3, "other": { "counterparty_timeout": { - "timestamp": "30000000000" + "block" : { + "height": 100, + "revision": 0 + } }, "ics_20": { "source" : "channel-0", @@ -423,7 +436,7 @@ "158456325028528675187087901673", { "amount": { - "intercept": "1000000000", + "intercept": "123456789", "slope": "0" }, "is_unit": false @@ -441,7 +454,7 @@ "assets": [ [ "237684487542793012780631852009", - "1000000000" + "123456789" ] ] }, diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index c6e24d04e08..7c344ba0ed5 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -227,7 +227,10 @@ "to": 3, "other": { "counterparty_timeout": { - "timestamp": "30000000000" + "block" : { + "height": 100, + "revision": 0 + } }, "ics_20": { "source" : "channel-0", From 2346294c6a8b8decd4c0a7fa04892a355ddc825e Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sat, 12 Aug 2023 17:36:31 +0100 Subject: [PATCH 07/17] timeout --- .../contracts/gateway/src/contract/execute.rs | 9 +- .../gateway/src/contract/ibc/ics20.rs | 6 +- .../gateway/src/contract/ibc/xcvm.rs | 11 +- .../cosmwasm/contracts/gateway/src/prelude.rs | 2 +- code/xcvm/lib/core/schema/raw/execute.json | 194 ++++-- code/xcvm/lib/core/schema/raw/query.json | 100 +++ .../raw/response_to_get_asset_by_id.json | 2 +- .../raw/response_to_get_ibc_ics20_route.json | 124 ++++ ...ponse_to_get_local_asset_by_reference.json | 158 +++++ code/xcvm/lib/core/schema/xc-core.json | 578 +++++++++++++++--- code/xcvm/lib/core/src/gateway/config.rs | 21 +- code/xcvm/lib/core/src/prelude.rs | 2 +- code/xcvm/lib/core/src/transport/ibc/mod.rs | 32 +- flake/osmosis.nix | 24 +- .../composable-centauri/flake-module.nix | 15 +- 15 files changed, 1092 insertions(+), 186 deletions(-) create mode 100644 code/xcvm/lib/core/schema/raw/response_to_get_ibc_ics20_route.json create mode 100644 code/xcvm/lib/core/schema/raw/response_to_get_local_asset_by_reference.json diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index af9e29f158e..6e5a3c8039a 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -37,14 +37,17 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) auth::Interpreter::authorise(deps.as_ref(), &info, msg.interpreter_origin.clone())?; if !msg.msg.assets.0.is_empty() { - super::ibc::ics20::handle_bridge_forward(auth, deps, info, msg) + super::ibc::ics20::handle_bridge_forward(auth, deps, info, msg, env.block) } else { - super::ibc::xcvm::handle_bridge_forward_no_assets(auth, deps, info, msg) + super::ibc::xcvm::handle_bridge_forward_no_assets(auth, deps, info, msg, env.block) } }, msg::ExecuteMsg::MessageHook(msg) => { - deps.api.debug(format!("xcvm::gateway::execute::message_hook {:?}", msg).as_str()); + deps.api + .debug(format!("xcvm::gateway::execute::message_hook {:?}", msg).as_str()); let auth = auth::WasmHook::authorise(deps.storage, &env, &info, msg.from_network_id)?; + // + // super::ibc::ics20::ics20_message_hook(auth, msg, env, info) }, msg::ExecuteMsg::Shortcut(msg) => handle_shortcut(deps, env, info, msg), diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index 3b25a0d26ef..dcc1174eac6 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -4,7 +4,8 @@ //! handles PFM and IBC wasm hooks use crate::prelude::*; use cosmwasm_std::{ - ensure_eq, wasm_execute, Binary, Coin, DepsMut, Env, MessageInfo, Response, Storage, SubMsg, + ensure_eq, wasm_execute, Binary, BlockInfo, Coin, DepsMut, Env, MessageInfo, Response, Storage, + SubMsg, }; use xc_core::{ gateway::{AssetItem, ExecuteMsg, ExecuteProgramMsg, GatewayId, OtherNetworkItem}, @@ -27,6 +28,7 @@ pub(crate) fn handle_bridge_forward( deps: DepsMut, info: MessageInfo, msg: xc_core::gateway::BridgeForwardMsg, + block: BlockInfo, ) -> Result { deps.api.debug(&format!( "xcvm::gateway:: forwarding over IBC ICS20 MEMO {}", @@ -71,7 +73,7 @@ pub(crate) fn handle_bridge_forward( let coin = Coin::new(amount.0, route.local_native_denom.clone()); - let msg = to_cw_message(deps.api, coin, route, packet)?; + let msg = to_cw_message(deps.api, coin, route, packet, block)?; deps.api.debug(&format!( "xcvm::gateway::ibc::ics20:: payload {}", &serde_json_wasm::to_string(&msg)? diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/xcvm.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/xcvm.rs index b92c0c3c5fd..ee37d6a9c55 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/xcvm.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/xcvm.rs @@ -13,10 +13,10 @@ use crate::{ }; use cosmwasm_std::{ - ensure_eq, wasm_execute, Binary, DepsMut, Env, Ibc3ChannelOpenResponse, IbcBasicResponse, - IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcMsg, - IbcOrder, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, - MessageInfo, Response, SubMsg, + ensure_eq, wasm_execute, Binary, BlockInfo, DepsMut, Env, Ibc3ChannelOpenResponse, + IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, + IbcChannelOpenResponse, IbcMsg, IbcOrder, IbcPacketAckMsg, IbcPacketReceiveMsg, + IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Response, SubMsg, }; use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId}; use xc_core::{ @@ -143,6 +143,7 @@ pub(crate) fn handle_bridge_forward_no_assets( deps: DepsMut, info: MessageInfo, msg: msg::BridgeForwardMsg, + block: BlockInfo, ) -> Result { ensure_eq!(msg.msg.assets.0.len(), 0, ContractError::CannotTransferAssets); let other = load_other(deps.storage, msg.to)?; @@ -178,6 +179,6 @@ pub(crate) fn handle_bridge_forward_no_assets( channel_id: channel_id.to_string(), data: Binary::from(packet.encode()), // TODO: should be a parameter or configuration - timeout: other.connection.counterparty_timeout, + timeout: other.connection.counterparty_timeout.absolute(block), })) } diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs b/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs index af3c5437c5c..f8fe02f87d4 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/prelude.rs @@ -1,6 +1,6 @@ +pub use alloc::format; pub use cosmwasm_std::{to_binary, Addr}; pub use cw_storage_plus::Map; pub use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId}; pub use serde::{Deserialize, Serialize}; pub use xc_core::gateway::config::*; -pub use alloc::format; \ No newline at end of file diff --git a/code/xcvm/lib/core/schema/raw/execute.json b/code/xcvm/lib/core/schema/raw/execute.json index d3a27227df0..90fdc7d2b70 100644 --- a/code/xcvm/lib/core/schema/raw/execute.json +++ b/code/xcvm/lib/core/schema/raw/execute.json @@ -464,6 +464,34 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "force_asset_to_network_map" + ], + "properties": { + "force_asset_to_network_map": { + "type": "object", + "required": [ + "other_asset", + "other_network", + "this_asset" + ], + "properties": { + "other_asset": { + "$ref": "#/definitions/AssetId" + }, + "other_network": { + "$ref": "#/definitions/NetworkId" + }, + "this_asset": { + "$ref": "#/definitions/AssetId" + } + } + } + }, + "additionalProperties": false + }, { "description": "Message sent by an admin to remove an asset from registry.", "type": "object", @@ -484,6 +512,33 @@ } }, "additionalProperties": false + }, + { + "description": "instantiates default interpreter on behalf of user `salt` - human string, converted to hex or base64 depending on implementation", + "type": "object", + "required": [ + "force_instantiate" + ], + "properties": { + "force_instantiate": { + "type": "object", + "required": [ + "user_origin" + ], + "properties": { + "salt": { + "type": [ + "string", + "null" + ] + }, + "user_origin": { + "$ref": "#/definitions/Addr" + } + } + } + }, + "additionalProperties": false } ] }, @@ -544,7 +599,7 @@ ] }, "salt": { - "description": "The program salt.", + "description": "The program salt. If JSON, than hex encoded non prefixed lower case string.", "type": "string" } } @@ -732,54 +787,6 @@ } ] }, - "IbcTimeout": { - "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", - "type": "object", - "properties": { - "block": { - "anyOf": [ - { - "$ref": "#/definitions/IbcTimeoutBlock" - }, - { - "type": "null" - } - ] - }, - "timestamp": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - } - }, - "IbcTimeoutBlock": { - "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", - "type": "object", - "required": [ - "height", - "revision" - ], - "properties": { - "height": { - "description": "block height after which the packet times out. the height within the given revision", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, "Ics20Channel": { "type": "object", "required": [ @@ -948,6 +955,7 @@ "$ref": "#/definitions/Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance" }, "salt": { + "description": "If JSON, than hex encoded non prefixed lower case string.", "type": "string" } } @@ -1060,7 +1068,7 @@ "description": "default timeout to use for direct send", "allOf": [ { - "$ref": "#/definitions/IbcTimeout" + "$ref": "#/definitions/RelativeTimeout" } ] }, @@ -1090,6 +1098,50 @@ "PFM": { "type": "object" }, + "Packet_for_Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance": { + "type": "object", + "required": [ + "assets", + "interpreter", + "program", + "salt", + "user_origin" + ], + "properties": { + "assets": { + "description": "The assets that were attached to the program.", + "allOf": [ + { + "$ref": "#/definitions/Funds_for_Displayed_for_uint128" + } + ] + }, + "interpreter": { + "description": "The interpreter that was the origin of this packet.", + "type": "string" + }, + "program": { + "description": "The protobuf encoded program.", + "allOf": [ + { + "$ref": "#/definitions/Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance" + } + ] + }, + "salt": { + "description": "The salt associated with the program.", + "type": "string" + }, + "user_origin": { + "description": "The user that originated the first XCVM call.", + "allOf": [ + { + "$ref": "#/definitions/UserOrigin" + } + ] + } + } + }, "Prefix": { "description": "given prefix you may form accounts from 32 bit addresses or partially identify chains", "oneOf": [ @@ -1153,6 +1205,7 @@ } }, "tag": { + "description": "If JSON, than hex encoded non prefixed lower case string.", "type": "string" } } @@ -1189,6 +1242,25 @@ } ] }, + "RelativeTimeout": { + "oneOf": [ + { + "description": "Timeout is relative to the current block timestamp of counter party", + "type": "object", + "required": [ + "seconds" + ], + "properties": { + "seconds": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + }, "ShortcutSubMsg": { "oneOf": [ { @@ -1238,22 +1310,10 @@ } ] }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, "UserId": { "description": "Arbitrary `User` type that represent the identity of a user on a given network, usually a public key.", "type": "string" @@ -1289,15 +1349,15 @@ "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" + "from_network_id", + "packet" ], "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, "from_network_id": { "$ref": "#/definitions/NetworkId" + }, + "packet": { + "$ref": "#/definitions/Packet_for_Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance" } } } diff --git a/code/xcvm/lib/core/schema/raw/query.json b/code/xcvm/lib/core/schema/raw/query.json index 53268118375..775c72f29cb 100644 --- a/code/xcvm/lib/core/schema/raw/query.json +++ b/code/xcvm/lib/core/schema/raw/query.json @@ -22,9 +22,58 @@ } }, "additionalProperties": false + }, + { + "description": "Returns [`AssetItem`] for an asset with given local reference.", + "type": "object", + "required": [ + "get_local_asset_by_reference" + ], + "properties": { + "get_local_asset_by_reference": { + "type": "object", + "required": [ + "reference" + ], + "properties": { + "reference": { + "$ref": "#/definitions/AssetReference" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_ibc_ics20_route" + ], + "properties": { + "get_ibc_ics20_route": { + "type": "object", + "required": [ + "for_asset", + "to_network" + ], + "properties": { + "for_asset": { + "$ref": "#/definitions/AssetId" + }, + "to_network": { + "$ref": "#/definitions/NetworkId" + } + } + } + }, + "additionalProperties": false } ], "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, "AssetId": { "description": "Newtype for XCVM assets ID. Must be unique for each asset 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.", "allOf": [ @@ -33,11 +82,62 @@ } ] }, + "AssetReference": { + "description": "Definition of an asset on this local chain to operate with", + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + } + } + } + }, + "additionalProperties": false + } + ] + }, "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_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 + }, + "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", + "format": "uint32", + "minimum": 0.0 } } } diff --git a/code/xcvm/lib/core/schema/raw/response_to_get_asset_by_id.json b/code/xcvm/lib/core/schema/raw/response_to_get_asset_by_id.json index 09b777b63cb..aade0feb1be 100644 --- a/code/xcvm/lib/core/schema/raw/response_to_get_asset_by_id.json +++ b/code/xcvm/lib/core/schema/raw/response_to_get_asset_by_id.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetAssetByIdResponse", + "title": "GetAssetResponse", "type": "object", "required": [ "asset" diff --git a/code/xcvm/lib/core/schema/raw/response_to_get_ibc_ics20_route.json b/code/xcvm/lib/core/schema/raw/response_to_get_ibc_ics20_route.json new file mode 100644 index 00000000000..19d40b17533 --- /dev/null +++ b/code/xcvm/lib/core/schema/raw/response_to_get_ibc_ics20_route.json @@ -0,0 +1,124 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetIbcIcs20RouteResponse", + "type": "object", + "required": [ + "route" + ], + "properties": { + "route": { + "$ref": "#/definitions/IbcIcs20Route" + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetId": { + "description": "Newtype for XCVM assets ID. Must be unique for each asset 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.", + "allOf": [ + { + "$ref": "#/definitions/Displayed_for_uint128" + } + ] + }, + "ChannelId": { + "type": "string" + }, + "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_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 + }, + "IbcIcs20Route": { + "description": "route is used to describe how to send a packet to another network", + "type": "object", + "required": [ + "channel_to_send_over", + "counterparty_timeout", + "from_network", + "gateway_to_send_to", + "ibc_ics_20_sender", + "local_native_denom", + "on_remote_asset", + "sender_gateway" + ], + "properties": { + "channel_to_send_over": { + "$ref": "#/definitions/ChannelId" + }, + "counterparty_timeout": { + "$ref": "#/definitions/RelativeTimeout" + }, + "from_network": { + "$ref": "#/definitions/NetworkId" + }, + "gateway_to_send_to": { + "$ref": "#/definitions/Addr" + }, + "ibc_ics_20_sender": { + "$ref": "#/definitions/IbcIcs20Sender" + }, + "local_native_denom": { + "type": "string" + }, + "on_remote_asset": { + "$ref": "#/definitions/AssetId" + }, + "sender_gateway": { + "$ref": "#/definitions/Addr" + } + } + }, + "IbcIcs20Sender": { + "oneOf": [ + { + "type": "string", + "enum": [ + "CosmosStargateIbcApplicationsTransferV1MsgTransfer", + "CosmWasmStd1_3" + ] + }, + { + "type": "object", + "required": [ + "SubstratePrecompile" + ], + "properties": { + "SubstratePrecompile": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "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", + "format": "uint32", + "minimum": 0.0 + }, + "RelativeTimeout": { + "oneOf": [ + { + "description": "Timeout is relative to the current block timestamp of counter party", + "type": "object", + "required": [ + "seconds" + ], + "properties": { + "seconds": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/code/xcvm/lib/core/schema/raw/response_to_get_local_asset_by_reference.json b/code/xcvm/lib/core/schema/raw/response_to_get_local_asset_by_reference.json new file mode 100644 index 00000000000..aade0feb1be --- /dev/null +++ b/code/xcvm/lib/core/schema/raw/response_to_get_local_asset_by_reference.json @@ -0,0 +1,158 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetAssetResponse", + "type": "object", + "required": [ + "asset" + ], + "properties": { + "asset": { + "$ref": "#/definitions/AssetItem" + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetId": { + "description": "Newtype for XCVM assets ID. Must be unique for each asset 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.", + "allOf": [ + { + "$ref": "#/definitions/Displayed_for_uint128" + } + ] + }, + "AssetItem": { + "type": "object", + "required": [ + "asset_id", + "from_network_id", + "local" + ], + "properties": { + "asset_id": { + "$ref": "#/definitions/AssetId" + }, + "bridged": { + "anyOf": [ + { + "$ref": "#/definitions/BridgeAsset" + }, + { + "type": "null" + } + ] + }, + "from_network_id": { + "$ref": "#/definitions/NetworkId" + }, + "local": { + "$ref": "#/definitions/AssetReference" + } + } + }, + "AssetReference": { + "description": "Definition of an asset on this local chain to operate with", + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "BridgeAsset": { + "type": "object", + "required": [ + "location_on_network" + ], + "properties": { + "location_on_network": { + "$ref": "#/definitions/ForeignAssetId" + } + } + }, + "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_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 + }, + "ForeignAssetId": { + "oneOf": [ + { + "type": "object", + "required": [ + "ibc_ics20" + ], + "properties": { + "ibc_ics20": { + "$ref": "#/definitions/PrefixedDenom" + } + }, + "additionalProperties": false + } + ] + }, + "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", + "format": "uint32", + "minimum": 0.0 + }, + "PrefixedDenom": { + "description": "A type that contains the base denomination for ICS20 and the source tracing information path.", + "type": "object", + "required": [ + "base_denom", + "trace_path" + ], + "properties": { + "base_denom": { + "description": "Base denomination of the relayed fungible token.", + "type": "string" + }, + "trace_path": { + "description": "A series of `{port-id}/{channel-id}`s for tracing the source of the token.", + "type": "string" + } + } + } + } +} diff --git a/code/xcvm/lib/core/schema/xc-core.json b/code/xcvm/lib/core/schema/xc-core.json index b522cce4c90..c4ddd22ecad 100644 --- a/code/xcvm/lib/core/schema/xc-core.json +++ b/code/xcvm/lib/core/schema/xc-core.json @@ -514,6 +514,34 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "force_asset_to_network_map" + ], + "properties": { + "force_asset_to_network_map": { + "type": "object", + "required": [ + "other_asset", + "other_network", + "this_asset" + ], + "properties": { + "other_asset": { + "$ref": "#/definitions/AssetId" + }, + "other_network": { + "$ref": "#/definitions/NetworkId" + }, + "this_asset": { + "$ref": "#/definitions/AssetId" + } + } + } + }, + "additionalProperties": false + }, { "description": "Message sent by an admin to remove an asset from registry.", "type": "object", @@ -534,6 +562,33 @@ } }, "additionalProperties": false + }, + { + "description": "instantiates default interpreter on behalf of user `salt` - human string, converted to hex or base64 depending on implementation", + "type": "object", + "required": [ + "force_instantiate" + ], + "properties": { + "force_instantiate": { + "type": "object", + "required": [ + "user_origin" + ], + "properties": { + "salt": { + "type": [ + "string", + "null" + ] + }, + "user_origin": { + "$ref": "#/definitions/Addr" + } + } + } + }, + "additionalProperties": false } ] }, @@ -594,7 +649,7 @@ ] }, "salt": { - "description": "The program salt.", + "description": "The program salt. If JSON, than hex encoded non prefixed lower case string.", "type": "string" } } @@ -782,54 +837,6 @@ } ] }, - "IbcTimeout": { - "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", - "type": "object", - "properties": { - "block": { - "anyOf": [ - { - "$ref": "#/definitions/IbcTimeoutBlock" - }, - { - "type": "null" - } - ] - }, - "timestamp": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - } - }, - "IbcTimeoutBlock": { - "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", - "type": "object", - "required": [ - "height", - "revision" - ], - "properties": { - "height": { - "description": "block height after which the packet times out. the height within the given revision", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - }, "Ics20Channel": { "type": "object", "required": [ @@ -998,6 +1005,7 @@ "$ref": "#/definitions/Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance" }, "salt": { + "description": "If JSON, than hex encoded non prefixed lower case string.", "type": "string" } } @@ -1110,7 +1118,7 @@ "description": "default timeout to use for direct send", "allOf": [ { - "$ref": "#/definitions/IbcTimeout" + "$ref": "#/definitions/RelativeTimeout" } ] }, @@ -1140,6 +1148,50 @@ "PFM": { "type": "object" }, + "Packet_for_Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance": { + "type": "object", + "required": [ + "assets", + "interpreter", + "program", + "salt", + "user_origin" + ], + "properties": { + "assets": { + "description": "The assets that were attached to the program.", + "allOf": [ + { + "$ref": "#/definitions/Funds_for_Displayed_for_uint128" + } + ] + }, + "interpreter": { + "description": "The interpreter that was the origin of this packet.", + "type": "string" + }, + "program": { + "description": "The protobuf encoded program.", + "allOf": [ + { + "$ref": "#/definitions/Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance" + } + ] + }, + "salt": { + "description": "The salt associated with the program.", + "type": "string" + }, + "user_origin": { + "description": "The user that originated the first XCVM call.", + "allOf": [ + { + "$ref": "#/definitions/UserOrigin" + } + ] + } + } + }, "Prefix": { "description": "given prefix you may form accounts from 32 bit addresses or partially identify chains", "oneOf": [ @@ -1203,6 +1255,7 @@ } }, "tag": { + "description": "If JSON, than hex encoded non prefixed lower case string.", "type": "string" } } @@ -1239,6 +1292,25 @@ } ] }, + "RelativeTimeout": { + "oneOf": [ + { + "description": "Timeout is relative to the current block timestamp of counter party", + "type": "object", + "required": [ + "seconds" + ], + "properties": { + "seconds": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + }, "ShortcutSubMsg": { "oneOf": [ { @@ -1288,22 +1360,10 @@ } ] }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, "Uint128": { "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", "type": "string" }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, "UserId": { "description": "Arbitrary `User` type that represent the identity of a user on a given network, usually a public key.", "type": "string" @@ -1339,15 +1399,15 @@ "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" + "from_network_id", + "packet" ], "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, "from_network_id": { "$ref": "#/definitions/NetworkId" + }, + "packet": { + "$ref": "#/definitions/Packet_for_Program_for_Array_of_Instruction_for_Array_of_uint8_and_CanonicalAddr_and_Funds_for_Balance" } } } @@ -1377,9 +1437,58 @@ } }, "additionalProperties": false + }, + { + "description": "Returns [`AssetItem`] for an asset with given local reference.", + "type": "object", + "required": [ + "get_local_asset_by_reference" + ], + "properties": { + "get_local_asset_by_reference": { + "type": "object", + "required": [ + "reference" + ], + "properties": { + "reference": { + "$ref": "#/definitions/AssetReference" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_ibc_ics20_route" + ], + "properties": { + "get_ibc_ics20_route": { + "type": "object", + "required": [ + "for_asset", + "to_network" + ], + "properties": { + "for_asset": { + "$ref": "#/definitions/AssetId" + }, + "to_network": { + "$ref": "#/definitions/NetworkId" + } + } + } + }, + "additionalProperties": false } ], "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, "AssetId": { "description": "Newtype for XCVM assets ID. Must be unique for each asset 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.", "allOf": [ @@ -1388,11 +1497,62 @@ } ] }, + "AssetReference": { + "description": "Definition of an asset on this local chain to operate with", + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + } + } + } + }, + "additionalProperties": false + } + ] + }, "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_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 + }, + "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", + "format": "uint32", + "minimum": 0.0 } } }, @@ -1401,7 +1561,289 @@ "responses": { "get_asset_by_id": { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetAssetByIdResponse", + "title": "GetAssetResponse", + "type": "object", + "required": [ + "asset" + ], + "properties": { + "asset": { + "$ref": "#/definitions/AssetItem" + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetId": { + "description": "Newtype for XCVM assets ID. Must be unique for each asset 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.", + "allOf": [ + { + "$ref": "#/definitions/Displayed_for_uint128" + } + ] + }, + "AssetItem": { + "type": "object", + "required": [ + "asset_id", + "from_network_id", + "local" + ], + "properties": { + "asset_id": { + "$ref": "#/definitions/AssetId" + }, + "bridged": { + "anyOf": [ + { + "$ref": "#/definitions/BridgeAsset" + }, + { + "type": "null" + } + ] + }, + "from_network_id": { + "$ref": "#/definitions/NetworkId" + }, + "local": { + "$ref": "#/definitions/AssetReference" + } + } + }, + "AssetReference": { + "description": "Definition of an asset on this local chain to operate with", + "oneOf": [ + { + "type": "object", + "required": [ + "native" + ], + "properties": { + "native": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "cw20" + ], + "properties": { + "cw20": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { + "$ref": "#/definitions/Addr" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "BridgeAsset": { + "type": "object", + "required": [ + "location_on_network" + ], + "properties": { + "location_on_network": { + "$ref": "#/definitions/ForeignAssetId" + } + } + }, + "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_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 + }, + "ForeignAssetId": { + "oneOf": [ + { + "type": "object", + "required": [ + "ibc_ics20" + ], + "properties": { + "ibc_ics20": { + "$ref": "#/definitions/PrefixedDenom" + } + }, + "additionalProperties": false + } + ] + }, + "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", + "format": "uint32", + "minimum": 0.0 + }, + "PrefixedDenom": { + "description": "A type that contains the base denomination for ICS20 and the source tracing information path.", + "type": "object", + "required": [ + "base_denom", + "trace_path" + ], + "properties": { + "base_denom": { + "description": "Base denomination of the relayed fungible token.", + "type": "string" + }, + "trace_path": { + "description": "A series of `{port-id}/{channel-id}`s for tracing the source of the token.", + "type": "string" + } + } + } + } + }, + "get_ibc_ics20_route": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetIbcIcs20RouteResponse", + "type": "object", + "required": [ + "route" + ], + "properties": { + "route": { + "$ref": "#/definitions/IbcIcs20Route" + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AssetId": { + "description": "Newtype for XCVM assets ID. Must be unique for each asset 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.", + "allOf": [ + { + "$ref": "#/definitions/Displayed_for_uint128" + } + ] + }, + "ChannelId": { + "type": "string" + }, + "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_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 + }, + "IbcIcs20Route": { + "description": "route is used to describe how to send a packet to another network", + "type": "object", + "required": [ + "channel_to_send_over", + "counterparty_timeout", + "from_network", + "gateway_to_send_to", + "ibc_ics_20_sender", + "local_native_denom", + "on_remote_asset", + "sender_gateway" + ], + "properties": { + "channel_to_send_over": { + "$ref": "#/definitions/ChannelId" + }, + "counterparty_timeout": { + "$ref": "#/definitions/RelativeTimeout" + }, + "from_network": { + "$ref": "#/definitions/NetworkId" + }, + "gateway_to_send_to": { + "$ref": "#/definitions/Addr" + }, + "ibc_ics_20_sender": { + "$ref": "#/definitions/IbcIcs20Sender" + }, + "local_native_denom": { + "type": "string" + }, + "on_remote_asset": { + "$ref": "#/definitions/AssetId" + }, + "sender_gateway": { + "$ref": "#/definitions/Addr" + } + } + }, + "IbcIcs20Sender": { + "oneOf": [ + { + "type": "string", + "enum": [ + "CosmosStargateIbcApplicationsTransferV1MsgTransfer", + "CosmWasmStd1_3" + ] + }, + { + "type": "object", + "required": [ + "SubstratePrecompile" + ], + "properties": { + "SubstratePrecompile": { + "$ref": "#/definitions/Addr" + } + }, + "additionalProperties": false + } + ] + }, + "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", + "format": "uint32", + "minimum": 0.0 + }, + "RelativeTimeout": { + "oneOf": [ + { + "description": "Timeout is relative to the current block timestamp of counter party", + "type": "object", + "required": [ + "seconds" + ], + "properties": { + "seconds": { + "type": "integer", + "format": "uint16", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + ] + } + } + }, + "get_local_asset_by_reference": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetAssetResponse", "type": "object", "required": [ "asset" diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index 14e7dd0bece..4b37d438fbc 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::{BlockInfo, IbcTimeout, Timestamp}; use ibc_rs_scale::core::ics24_host::identifier::ChannelId; use crate::{ @@ -127,13 +127,30 @@ pub struct IcsPair { pub sink: ChannelId, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Encode, Decode)] +#[serde(rename_all = "snake_case")] +#[cfg_attr(feature = "std", derive(schemars::JsonSchema))] +pub enum RelativeTimeout { + /// Timeout is relative to the current block timestamp of counter party + Seconds(u16), +} + +impl RelativeTimeout { + pub fn absolute(&self, block: BlockInfo) -> IbcTimeout { + match self { + RelativeTimeout::Seconds(seconds) => + IbcTimeout::with_timestamp(block.time.plus_seconds(*seconds as u64)), + } + } +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] pub struct OtherNetworkItem { pub ics_20: Option, /// default timeout to use for direct send - pub counterparty_timeout: IbcTimeout, + pub counterparty_timeout: RelativeTimeout, /// if there is custom IBC channel opened pub xcvm_channel: Option, } diff --git a/code/xcvm/lib/core/src/prelude.rs b/code/xcvm/lib/core/src/prelude.rs index 766b59bc4f1..3558b9fa792 100644 --- a/code/xcvm/lib/core/src/prelude.rs +++ b/code/xcvm/lib/core/src/prelude.rs @@ -1,10 +1,10 @@ pub use alloc::{ boxed::Box, collections::VecDeque, + format, string::{String, ToString}, vec, vec::Vec, - format, }; pub use core::{fmt::Display, str::FromStr}; pub use cosmwasm_std::{Addr, Binary, Coin, HexBinary, Uint128}; diff --git a/code/xcvm/lib/core/src/transport/ibc/mod.rs b/code/xcvm/lib/core/src/transport/ibc/mod.rs index 8b99a95d744..6d7a63088d1 100644 --- a/code/xcvm/lib/core/src/transport/ibc/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/mod.rs @@ -1,8 +1,15 @@ pub mod ics20; pub mod picasso; -use crate::{prelude::*, shared::XcPacket, AssetId, NetworkId, gateway}; -use cosmwasm_std::{to_binary, CosmosMsg, IbcEndpoint, IbcTimeout, StdResult, WasmMsg, Api}; +use crate::{ + gateway::{self, RelativeTimeout}, + prelude::*, + shared::XcPacket, + AssetId, NetworkId, +}; +use cosmwasm_std::{ + to_binary, Api, BlockInfo, CosmosMsg, IbcEndpoint, IbcTimeout, StdResult, WasmMsg, +}; use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; @@ -41,7 +48,7 @@ pub struct IbcIcs20Route { pub channel_to_send_over: ChannelId, pub sender_gateway: Addr, pub gateway_to_send_to: Addr, - pub counterparty_timeout: IbcTimeout, + pub counterparty_timeout: RelativeTimeout, pub ibc_ics_20_sender: IbcIcs20Sender, pub on_remote_asset: AssetId, } @@ -51,8 +58,12 @@ pub fn to_cw_message( coin: Coin, route: IbcIcs20Route, packet: XcPacket, + block: BlockInfo, ) -> StdResult> { - let msg = gateway::ExecuteMsg::MessageHook(XcMessageData { from_network_id: route.from_network, packet }); + let msg = gateway::ExecuteMsg::MessageHook(XcMessageData { + from_network_id: route.from_network, + packet, + }); let memo = SendMemo { inner: Memo { wasm: Some(Callback { @@ -71,7 +82,7 @@ pub fn to_cw_message( channel_id: route.channel_to_send_over.clone(), to_address: route.gateway_to_send_to, amount: coin, - timeout: route.counterparty_timeout, + timeout: route.counterparty_timeout.absolute(block), memo: Some(memo), }; Ok(WasmMsg::Execute { @@ -96,18 +107,19 @@ pub fn to_cw_message( token: Some(Coin { denom: coin.denom, amount: coin.amount.to_string() }), sender: route.sender_gateway.to_string(), receiver: route.gateway_to_send_to.to_string(), - timeout_height: route.counterparty_timeout.block().map(|x| { - ibc_proto::ibc::core::client::v1::Height { + timeout_height: route.counterparty_timeout.absolute(block.clone()).block().map( + |x| ibc_proto::ibc::core::client::v1::Height { revision_height: x.height, revision_number: x.revision, - } - }), + }, + ), timeout_timestamp: route .counterparty_timeout + .absolute(block) .timestamp() .map(|x| x.seconds()) .unwrap_or_default(), - memo : "".into(), + memo, } .encode_to_vec(); let value = Binary::from(value); diff --git a/flake/osmosis.nix b/flake/osmosis.nix index e212697fc78..7b24b03e140 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -1,20 +1,10 @@ { self, ... }: { - perSystem = - { self' - , pkgs - , systemCommonRust - , subnix - , lib - , system - , devnetTools - , cosmosTools - , ... - }: + perSystem = { self', pkgs, systemCommonRust, subnix, lib, system, devnetTools + , cosmosTools, ... }: let devnet-root-directory = cosmosTools.devnet-root-directory; validator-key = cosmosTools.validators.osmosis; - in - { + in { packages = rec { osmosisd = pkgs.writeShellApplication { name = "osmosisd"; @@ -312,7 +302,7 @@ "other": { "counterparty_timeout": { "block" : { - "height": 100, + "height": 100000, "revision": 0 } }, @@ -436,7 +426,7 @@ "158456325028528675187087901673", { "amount": { - "intercept": "123456789", + "intercept": "1234567890", "slope": "0" }, "is_unit": false @@ -454,7 +444,7 @@ "assets": [ [ "237684487542793012780631852009", - "123456789" + "1234567890" ] ] }, @@ -464,7 +454,7 @@ EOF ) - "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$TRANSFER_PICA_TO_OSMOSIS" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 1000000000"$FEE" --amount 1000000000"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace + "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$TRANSFER_PICA_TO_OSMOSIS" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 1000000000"$FEE" --amount 1234567890"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace sleep "$BLOCK_SECONDS" ''; }; diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index 7c344ba0ed5..98b93b0577a 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -103,7 +103,7 @@ sleep $BLOCK_SECONDS - "$BINARY" tx wasm instantiate2 $GATEWAY_CODE_ID "$INSTANTIATE" "1234" --label "xc-gateway" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" --admin "$KEY" + "$BINARY" tx wasm instantiate2 $GATEWAY_CODE_ID "$INSTANTIATE" "1234" --label "xc-gateway" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166$FEE --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" --admin "$KEY" --amount 1000000000000$FEE sleep $BLOCK_SECONDS GATEWAY_CONTRACT_ADDRESS=$("$BINARY" query wasm list-contract-by-code "$GATEWAY_CODE_ID" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --home "$CHAIN_DATA" | dasel --read json '.contracts.[0]' --write yaml) @@ -227,10 +227,7 @@ "to": 3, "other": { "counterparty_timeout": { - "block" : { - "height": 100, - "revision": 0 - } + "seconds" : 120 }, "ics_20": { "source" : "channel-0", @@ -398,7 +395,7 @@ "158456325028528675187087900673", { "amount": { - "intercept": "1000000000", + "intercept": "1234567890", "slope": "0" }, "is_unit": false @@ -416,7 +413,7 @@ "assets": [ [ "158456325028528675187087900673", - "1000000000" + "1234567890" ] ] }, @@ -429,7 +426,7 @@ # check route "$BINARY" query wasm contract-state smart "$GATEWAY_CONTRACT_ADDRESS" '{ "get_ibc_ics20_route" : { "for_asset" : "158456325028528675187087900673", "to_network": 3 } }' --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --home "$CHAIN_DATA" - "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$TRANSFER_PICA_TO_OSMOSIS" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 1000000000"$FEE" --amount 1000000000"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace + "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$TRANSFER_PICA_TO_OSMOSIS" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 1000000000"$FEE" --amount 1234567890"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace sleep "$BLOCK_SECONDS" ''; }; @@ -554,7 +551,7 @@ PORT=26657 FEE=ppica BINARY=centaurid - "$BINARY" tx ibc-transfer transfer transfer channel-0 osmo12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n 10000000000ppica --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace + "$BINARY" tx ibc-transfer transfer transfer channel-0 osmo1x99pkz8mk7msmptegg887wy46vrusl7kk0sudvaf2uh2k8qz7spsyy4mg8 9876543210ppica --memo '{ "wasm" : { "contract" : "osmo1x99pkz8mk7msmptegg887wy46vrusl7kk0sudvaf2uh2k8qz7spsyy4mg8" } }' --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166"$FEE" --log_level trace --keyring-backend test --home "$CHAIN_DATA" --from ${cosmosTools.xcvm.moniker} --keyring-dir "$KEYRING_TEST" --trace --log_level trace ''; }; }; From 0922867d2eae124248d48675fdef75c36fe6ec0e Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 12:55:56 +0100 Subject: [PATCH 08/17] more errors --- .../cosmwasm/contracts/gateway/src/assets.rs | 4 ++-- code/xcvm/cosmwasm/contracts/gateway/src/auth.rs | 11 ++++++++--- .../contracts/gateway/src/contract/execute.rs | 4 ++-- .../contracts/gateway/src/contract/ibc/ics20.rs | 16 +++++++++++----- .../xcvm/cosmwasm/contracts/gateway/src/error.rs | 6 ++++-- .../contracts/gateway/src/interpreter.rs | 4 ++-- code/xcvm/cosmwasm/tests/src/tests/framework.rs | 2 +- code/xcvm/lib/core/src/gateway/config.rs | 11 ++++++++--- code/xcvm/lib/core/src/gateway/sad.json | 1 - .../xcvm/lib/core/src/transport/ibc/ics20/mod.rs | 2 +- code/xcvm/lib/core/src/transport/ibc/mod.rs | 2 +- 11 files changed, 40 insertions(+), 23 deletions(-) delete mode 100644 code/xcvm/lib/core/src/gateway/sad.json diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs index 310d4cea1c2..c050667e9b7 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs @@ -15,7 +15,7 @@ use xc_core::{AssetId, NetworkId}; pub(crate) fn force_asset(_: auth::Admin, deps: DepsMut, msg: AssetItem) -> Result { let config = crate::state::load(deps.storage)?; ASSETS.save(deps.storage, msg.asset_id, &msg)?; - if msg.from_network_id == config.here_id { + if msg.network_id == config.here_id { LOCAL_ASSETS.save(deps.storage, msg.local.clone(), &msg)?; } Ok(Response::new().add_event( @@ -50,7 +50,7 @@ pub(crate) fn force_remove_asset( let config = crate::state::load(deps.storage)?; let asset = ASSETS.load(deps.storage, asset_id)?; ASSETS.remove(deps.storage, asset_id); - if asset.from_network_id == config.here_id { + if asset.network_id == config.here_id { LOCAL_ASSETS.remove(deps.storage, asset.local); } Ok(Response::new() diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs index 17d3f488dc1..45b5efbd073 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs @@ -45,12 +45,17 @@ impl Auth { network_id: NetworkId, ) -> Result { let this = state::load(storage)?; - let this_to_other: OtherNetworkItem = - state::NETWORK_TO_NETWORK.load(storage, (this.here_id, network_id))?; + let this_to_other: OtherNetworkItem = state::NETWORK_TO_NETWORK + .load(storage, (this.here_id, network_id)) + .map_err(|_| ContractError::NoConnectionInformationFromThisToOtherNetwork( + this.here_id, + network_id, + ))?; let sender = state::NETWORK .load(storage, network_id)? .gateway - .ok_or(ContractError::NotAuthorized)?; + .ok_or(ContractError::GatewayForNetworkNotFound(network_id))?; + let sender = match sender { msg::GatewayId::CosmWasm { contract, .. } => contract.to_string(), }; diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index 6e5a3c8039a..636007ef931 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -45,9 +45,9 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) msg::ExecuteMsg::MessageHook(msg) => { deps.api .debug(format!("xcvm::gateway::execute::message_hook {:?}", msg).as_str()); + let auth = auth::WasmHook::authorise(deps.storage, &env, &info, msg.from_network_id)?; - // - // + super::ibc::ics20::ics20_message_hook(auth, msg, env, info) }, msg::ExecuteMsg::Shortcut(msg) => handle_shortcut(deps, env, info, msg), diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index dcc1174eac6..b9436d9c96c 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -39,17 +39,23 @@ pub(crate) fn handle_bridge_forward( // 1. recurse on program until can with memo // 2. as soon as see no Spawn/Transfer, stop memo and do Wasm call with remaining Packet + + let (local_asset, amount) = msg.msg.assets.0.get(0).expect("proved above"); + + let route: IbcIcs20Route = get_route(deps.storage, msg.to, *local_asset)?; + + let asset = msg.msg.assets.0.get(0).map(|(_, amount)| { + (route.on_remote_asset, *amount) + }).expect("not empty"); + let packet = XcPacket { interpreter: String::from(info.sender).into_bytes(), user_origin: msg.interpreter_origin.user_origin, salt: msg.msg.salt, program: msg.msg.program, - assets: msg.msg.assets, + assets: vec![asset].into(), }; - let (local_asset, amount) = packet.assets.0.get(0).expect("proved above"); - - let route = get_route(deps.storage, msg.to, *local_asset)?; deps.api.debug(&format!( "xcvm::gateway::ibc::ics20 route {}", &serde_json_wasm::to_string(&route)? @@ -96,7 +102,7 @@ pub fn get_route( .map_err(|_| ContractError::UnknownTargetNetwork)?; let this_to_other: OtherNetworkItem = state::NETWORK_TO_NETWORK .load(storage, (this.network_id, to)) - .map_err(|_| ContractError::NoConnectionInformationFromThisToOtherNetwork)?; + .map_err(|_| ContractError::NoConnectionInformationFromThisToOtherNetwork(this.network_id, to))?; let asset: AssetItem = state::assets::ASSETS .load(storage, this_asset_id) .map_err(|_| ContractError::AssetNotFoundById(this_asset_id))?; diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/error.rs b/code/xcvm/cosmwasm/contracts/gateway/src/error.rs index 07af55a08b3..b3ad18d619c 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/error.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/error.rs @@ -65,13 +65,15 @@ pub enum ContractError { NetworkConfig, #[error("Unknown target network")] UnknownTargetNetwork, - #[error("No connection information from this to other network")] - NoConnectionInformationFromThisToOtherNetwork, + #[error("No connection information from this {0} to other network {1}")] + NoConnectionInformationFromThisToOtherNetwork(NetworkId, NetworkId), #[error("Asset {0} not found by id")] AssetNotFoundById(AssetId), #[error("Asset {0} cannot be transferred to network {1}")] AssetCannotBeTransferredToNetwork(AssetId, NetworkId), + #[error("Gateway for network {0} not found")] + GatewayForNetworkNotFound(NetworkId), } impl From for ContractError { diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/interpreter.rs b/code/xcvm/cosmwasm/contracts/gateway/src/interpreter.rs index f94ad911db7..c79bb6aa6eb 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/interpreter.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/interpreter.rs @@ -20,13 +20,13 @@ pub(crate) fn force_instantiate( gateway: Addr, deps: DepsMut, user_origin: Addr, - salt: Option, + salt: String, ) -> Result { let config = load_this(deps.storage)?; let interpreter_code_id = match config.gateway.expect("expected setup") { GatewayId::CosmWasm { interpreter_code_id, .. } => interpreter_code_id, }; - let salt = salt.map_or(<_>::default(), |x| x.into_bytes()); + let salt = salt.into_bytes(); let call_origin = CallOrigin::Local { user: user_origin }; let interpreter_origin = diff --git a/code/xcvm/cosmwasm/tests/src/tests/framework.rs b/code/xcvm/cosmwasm/tests/src/tests/framework.rs index a4ad96ef581..448cee7a217 100644 --- a/code/xcvm/cosmwasm/tests/src/tests/framework.rs +++ b/code/xcvm/cosmwasm/tests/src/tests/framework.rs @@ -274,7 +274,7 @@ impl TestVM> { tx.gas, xc_core::gateway::ExecuteMsg::Config(ConfigSubMsg::ForceAsset(AssetItem { asset_id, - from_network_id: todo!("restore"), + network_id: todo!("restore"), local: xc_core::gateway::AssetReference::Cw20 { contract: asset_address.clone().into(), }, diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index 4b37d438fbc..c862b816512 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::{BlockInfo, IbcTimeout, Timestamp}; +use cosmwasm_std::{BlockInfo, IbcTimeout,}; use ibc_rs_scale::core::ics24_host::identifier::ChannelId; use crate::{ @@ -127,6 +127,8 @@ pub struct IcsPair { pub sink: ChannelId, } +/// relative timeout to CW/IBC-rs time. +/// very small, assumed messages are arriving fast enough, like less than hours #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Encode, Decode)] #[serde(rename_all = "snake_case")] #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] @@ -191,7 +193,8 @@ pub enum ConfigSubMsg { /// `salt` - human string, converted to hex or base64 depending on implementation ForceInstantiate { user_origin: Addr, - salt: Option, + #[serde(skip_serializing_if = "String::is_empty", default)] + salt: String, }, } @@ -230,8 +233,10 @@ pub enum GatewayId { pub struct AssetItem { pub asset_id: AssetId, - pub from_network_id: NetworkId, + /// network id on which this asset id can be used locally + pub network_id: NetworkId, pub local: AssetReference, + /// if asset was bridged, it would have way to identify bridge/source/channel pub bridged: Option, } diff --git a/code/xcvm/lib/core/src/gateway/sad.json b/code/xcvm/lib/core/src/gateway/sad.json deleted file mode 100644 index 60b4b6b05d2..00000000000 --- a/code/xcvm/lib/core/src/gateway/sad.json +++ /dev/null @@ -1 +0,0 @@ -"{\"execute_program\":{\"execute_program\":{\"salt\":\"737061776e5f776974685f6173736574\",\"program\":{\"tag\":\"737061776e5f776974685f6173736574\",\"instructions\":[{\"spawn\":{\"network\":2,\"salt\":\"737061776e5f776974685f6173736574\",\"assets\":[[\"237684487542793012780631852009\",{\"amount\":{\"intercept\":\"1000000000\",\"slope\":\"0\"},\"is_unit\":false}]],\"program\":{\"tag\":\"737061776e5f776974685f6173736574\",\"instructions\":[]}}}]},\"assets\":[[\"237684487542793012780631852009\",\"1000000000\"]]},\"tip\":\"osmo12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n\"}} \ No newline at end of file diff --git a/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs b/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs index f08499b2483..ee547354021 100644 --- a/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs @@ -34,4 +34,4 @@ impl Memo { pub fn forward(forward: ForwardingMemo) -> Self { Self { forward: Some(forward), wasm: None } } -} +} \ No newline at end of file diff --git a/code/xcvm/lib/core/src/transport/ibc/mod.rs b/code/xcvm/lib/core/src/transport/ibc/mod.rs index 6d7a63088d1..e5655ef2633 100644 --- a/code/xcvm/lib/core/src/transport/ibc/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/mod.rs @@ -8,7 +8,7 @@ use crate::{ AssetId, NetworkId, }; use cosmwasm_std::{ - to_binary, Api, BlockInfo, CosmosMsg, IbcEndpoint, IbcTimeout, StdResult, WasmMsg, + to_binary, Api, BlockInfo, CosmosMsg, IbcEndpoint, StdResult, WasmMsg, }; use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; From 566432fb7e16e5c429c83fad2eff631f778d7f0e Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 13:30:15 +0100 Subject: [PATCH 09/17] test that encoding in hook compatible with encoding in go --- code/xcvm/cosmwasm/contracts/gateway/src/auth.rs | 1 + code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs index 45b5efbd073..6b0cc7e186e 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs @@ -65,6 +65,7 @@ impl Auth { xc_core::transport::ibc::ics20::hook::derive_intermediate_sender( &channel, &sender, "", )?; + Self::new(hash_of_channel_and_sender == info.sender && info.sender == env.contract.address) } } diff --git a/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs b/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs index d9cbe65ae67..b200bce4e3e 100644 --- a/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs +++ b/code/xcvm/lib/core/src/transport/ibc/ics20/hook.rs @@ -28,7 +28,14 @@ pub enum IBCLifecycleComplete { }, } -/// from Go code to make compliant wasm hook +/// derives the sender address to be used when calling wasm hooks +/// https://github.com/osmosis-labs/osmosis/blob/master/x/ibc-hooks/keeper/keeper.go#L170 +/// ```rust +/// let channel = ibc_rs_scale::core::ics24_host::identifier::ChannelId::new(0); +/// let original_sender = "juno12smx2wdlyttvyzvzg54y2vnqwq2qjatezqwqxu"; +/// let hashed_sender = xc_core::transport::ibc::ics20::hook::derive_intermediate_sender(&channel, original_sender, "osmo").expect("new address"); +/// assert_eq!(hashed_sender, "osmo1nt0pudh879m6enw4j6z4mvyu3vmwawjv5gr7xw6lvhdsdpn3m0qs74xdjl"); +/// ``` pub fn derive_intermediate_sender( channel: &ChannelId, original_sender: &str, From fe01770ee18637a7a1eb5b231cf851aea88e64eb Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 13:46:46 +0100 Subject: [PATCH 10/17] couple fixes --- .../cosmwasm/contracts/gateway/src/assets.rs | 4 ++-- code/xcvm/cosmwasm/contracts/gateway/src/auth.rs | 16 ++++++++++------ .../cosmwasm/contracts/gateway/src/network.rs | 8 ++++---- code/xcvm/cosmwasm/tests/src/tests/framework.rs | 2 +- code/xcvm/lib/core/src/gateway/config.rs | 4 ++-- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs index c050667e9b7..582bb7ebcfe 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/assets.rs @@ -15,7 +15,7 @@ use xc_core::{AssetId, NetworkId}; pub(crate) fn force_asset(_: auth::Admin, deps: DepsMut, msg: AssetItem) -> Result { let config = crate::state::load(deps.storage)?; ASSETS.save(deps.storage, msg.asset_id, &msg)?; - if msg.network_id == config.here_id { + if msg.network_id == config.network_id { LOCAL_ASSETS.save(deps.storage, msg.local.clone(), &msg)?; } Ok(Response::new().add_event( @@ -50,7 +50,7 @@ pub(crate) fn force_remove_asset( let config = crate::state::load(deps.storage)?; let asset = ASSETS.load(deps.storage, asset_id)?; ASSETS.remove(deps.storage, asset_id); - if asset.network_id == config.here_id { + if asset.network_id == config.network_id { LOCAL_ASSETS.remove(deps.storage, asset.local); } Ok(Response::new() diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs index 6b0cc7e186e..82e8fdb3852 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs @@ -1,7 +1,7 @@ //! Module with authorisation checks. use crate::{ error::{ContractError, Result}, - msg, state, + msg, state, network, }; use cosmwasm_std::{Deps, Env, MessageInfo, Storage}; use xc_core::{gateway::OtherNetworkItem, NetworkId}; @@ -44,13 +44,17 @@ impl Auth { info: &MessageInfo, network_id: NetworkId, ) -> Result { - let this = state::load(storage)?; + let this = network::load_this(storage)?; let this_to_other: OtherNetworkItem = state::NETWORK_TO_NETWORK - .load(storage, (this.here_id, network_id)) + .load(storage, (this.network_id, network_id)) .map_err(|_| ContractError::NoConnectionInformationFromThisToOtherNetwork( - this.here_id, + this.network_id, network_id, ))?; + let prefix = this.accounts.map(|x| match x { + msg::Prefix::SS58(prefix) => prefix.to_string(), + msg::Prefix::Bech(prefix) => prefix, + }).unwrap_or_default(); let sender = state::NETWORK .load(storage, network_id)? .gateway @@ -63,9 +67,9 @@ impl Auth { let channel = this_to_other.ics_20.ok_or(ContractError::ICS20NotFound)?.source; let hash_of_channel_and_sender = xc_core::transport::ibc::ics20::hook::derive_intermediate_sender( - &channel, &sender, "", + &channel, &sender, &prefix, )?; - + Self::new(hash_of_channel_and_sender == info.sender && info.sender == env.contract.address) } } diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/network.rs b/code/xcvm/cosmwasm/contracts/gateway/src/network.rs index 4abe3b47473..a0f9292264f 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/network.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/network.rs @@ -8,7 +8,7 @@ use crate::error::{ContractError, Result}; pub fn load_this(storage: &dyn Storage) -> Result { state::load(storage) - .and_then(|this| NETWORK.load(storage, this.here_id)) + .and_then(|this| NETWORK.load(storage, this.network_id)) .map_err(|_| ContractError::NetworkConfig) } @@ -19,10 +19,10 @@ pub struct OtherNetwork { pub connection: OtherNetworkItem, } -pub fn load_other(storage: &dyn Storage, _other: NetworkId) -> Result { +pub fn load_other(storage: &dyn Storage, other: NetworkId) -> Result { let this = state::load(storage)?; - let other = NETWORK.load(storage, this.here_id)?; - let connection = NETWORK_TO_NETWORK.load(storage, (this.here_id, other.network_id))?; + let other = NETWORK.load(storage, other)?; + let connection = NETWORK_TO_NETWORK.load(storage, (this.network_id, other.network_id))?; Ok(OtherNetwork { network: other, connection }) } diff --git a/code/xcvm/cosmwasm/tests/src/tests/framework.rs b/code/xcvm/cosmwasm/tests/src/tests/framework.rs index 448cee7a217..a2c10050041 100644 --- a/code/xcvm/cosmwasm/tests/src/tests/framework.rs +++ b/code/xcvm/cosmwasm/tests/src/tests/framework.rs @@ -223,7 +223,7 @@ impl TestVM<()> { tx.info.clone(), tx.gas, xc_core::gateway::InstantiateMsg(HereItem { - here_id: self.network_id, + network_id: self.network_id, admin: todo!(), }), )?; diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index c862b816512..592798c367e 100644 --- a/code/xcvm/lib/core/src/gateway/config.rs +++ b/code/xcvm/lib/core/src/gateway/config.rs @@ -207,8 +207,8 @@ pub struct InstantiateMsg(pub HereItem); #[serde(rename_all = "snake_case")] #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] pub struct HereItem { - /// Network ID of this network - pub here_id: NetworkId, + /// Network ID of this network where contract is deployed + pub network_id: NetworkId, /// The admin which is allowed to update the bridge list. pub admin: Addr, } From 107544f33ca95c8f0ce64c0904743c9fd2d1a5dc Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 14:00:22 +0100 Subject: [PATCH 11/17] god bless the run --- .../cosmwasm/contracts/gateway/src/auth.rs | 40 +++++++++++-------- .../contracts/gateway/src/contract/execute.rs | 6 +-- .../gateway/src/contract/ibc/ics20.rs | 22 +++++----- .../cosmwasm/contracts/gateway/src/error.rs | 2 + code/xcvm/lib/core/src/gateway/config.rs | 2 +- .../lib/core/src/transport/ibc/ics20/mod.rs | 2 +- code/xcvm/lib/core/src/transport/ibc/mod.rs | 4 +- 7 files changed, 45 insertions(+), 33 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs index 82e8fdb3852..14da0956f43 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/auth.rs @@ -1,9 +1,9 @@ //! Module with authorisation checks. use crate::{ error::{ContractError, Result}, - msg, state, network, + msg, network, state, }; -use cosmwasm_std::{Deps, Env, MessageInfo, Storage}; +use cosmwasm_std::{Deps, Env, MessageInfo}; use xc_core::{gateway::OtherNetworkItem, NetworkId}; /// Authorisation token indicating call is authorised according to policy @@ -39,24 +39,29 @@ impl Auth { impl Auth { pub(crate) fn authorise( - storage: &dyn Storage, + deps: Deps, env: &Env, info: &MessageInfo, network_id: NetworkId, ) -> Result { - let this = network::load_this(storage)?; + let this = network::load_this(deps.storage)?; let this_to_other: OtherNetworkItem = state::NETWORK_TO_NETWORK - .load(storage, (this.network_id, network_id)) - .map_err(|_| ContractError::NoConnectionInformationFromThisToOtherNetwork( - this.network_id, - network_id, - ))?; - let prefix = this.accounts.map(|x| match x { - msg::Prefix::SS58(prefix) => prefix.to_string(), - msg::Prefix::Bech(prefix) => prefix, - }).unwrap_or_default(); + .load(deps.storage, (this.network_id, network_id)) + .map_err(|_| { + ContractError::NoConnectionInformationFromThisToOtherNetwork( + this.network_id, + network_id, + ) + })?; + let prefix = this + .accounts + .map(|x| match x { + msg::Prefix::SS58(prefix) => prefix.to_string(), + msg::Prefix::Bech(prefix) => prefix, + }) + .unwrap_or_default(); let sender = state::NETWORK - .load(storage, network_id)? + .load(deps.storage, network_id)? .gateway .ok_or(ContractError::GatewayForNetworkNotFound(network_id))?; @@ -69,8 +74,11 @@ impl Auth { xc_core::transport::ibc::ics20::hook::derive_intermediate_sender( &channel, &sender, &prefix, )?; - - Self::new(hash_of_channel_and_sender == info.sender && info.sender == env.contract.address) + deps.api.debug(&format!( + "xcvm::gateway:auth:: {0} {1}", + &hash_of_channel_and_sender, &info.sender + )); + Self::new(hash_of_channel_and_sender == info.sender || info.sender == env.contract.address) } } diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index 636007ef931..41bfab5c8af 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -45,9 +45,9 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) msg::ExecuteMsg::MessageHook(msg) => { deps.api .debug(format!("xcvm::gateway::execute::message_hook {:?}", msg).as_str()); - - let auth = auth::WasmHook::authorise(deps.storage, &env, &info, msg.from_network_id)?; - + + let auth = auth::WasmHook::authorise(deps.as_ref(), &env, &info, msg.from_network_id)?; + super::ibc::ics20::ics20_message_hook(auth, msg, env, info) }, msg::ExecuteMsg::Shortcut(msg) => handle_shortcut(deps, env, info, msg), diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index b9436d9c96c..8b905879812 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -39,14 +39,17 @@ pub(crate) fn handle_bridge_forward( // 1. recurse on program until can with memo // 2. as soon as see no Spawn/Transfer, stop memo and do Wasm call with remaining Packet - let (local_asset, amount) = msg.msg.assets.0.get(0).expect("proved above"); let route: IbcIcs20Route = get_route(deps.storage, msg.to, *local_asset)?; - - let asset = msg.msg.assets.0.get(0).map(|(_, amount)| { - (route.on_remote_asset, *amount) - }).expect("not empty"); + + let asset = msg + .msg + .assets + .0 + .get(0) + .map(|(_, amount)| (route.on_remote_asset, *amount)) + .expect("not empty"); let packet = XcPacket { interpreter: String::from(info.sender).into_bytes(), @@ -100,9 +103,10 @@ pub fn get_route( let other: NetworkItem = state::NETWORK .load(storage, to) .map_err(|_| ContractError::UnknownTargetNetwork)?; - let this_to_other: OtherNetworkItem = state::NETWORK_TO_NETWORK - .load(storage, (this.network_id, to)) - .map_err(|_| ContractError::NoConnectionInformationFromThisToOtherNetwork(this.network_id, to))?; + let this_to_other: OtherNetworkItem = + state::NETWORK_TO_NETWORK.load(storage, (this.network_id, to)).map_err(|_| { + ContractError::NoConnectionInformationFromThisToOtherNetwork(this.network_id, to) + })?; let asset: AssetItem = state::assets::ASSETS .load(storage, this_asset_id) .map_err(|_| ContractError::AssetNotFoundById(this_asset_id))?; @@ -161,7 +165,7 @@ fn ensure_anonymous(program: &XcProgram) -> Result<()> { match ix { xc_core::Instruction::Transfer { .. } => {}, xc_core::Instruction::Spawn { program, .. } => ensure_anonymous(program)?, - _ => Err(ContractError::NotAuthorized)?, + _ => Err(ContractError::AnonymousCallsCanDoOnlyLimitedSetOfActions)?, } } Ok(()) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/error.rs b/code/xcvm/cosmwasm/contracts/gateway/src/error.rs index b3ad18d619c..e5107c173f3 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/error.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/error.rs @@ -74,6 +74,8 @@ pub enum ContractError { AssetCannotBeTransferredToNetwork(AssetId, NetworkId), #[error("Gateway for network {0} not found")] GatewayForNetworkNotFound(NetworkId), + #[error("Anonymous calls can do only limitet set of actions")] + AnonymousCallsCanDoOnlyLimitedSetOfActions, } impl From for ContractError { diff --git a/code/xcvm/lib/core/src/gateway/config.rs b/code/xcvm/lib/core/src/gateway/config.rs index 592798c367e..3380265803b 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::{BlockInfo, IbcTimeout,}; +use cosmwasm_std::{BlockInfo, IbcTimeout}; use ibc_rs_scale::core::ics24_host::identifier::ChannelId; use crate::{ diff --git a/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs b/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs index ee547354021..f08499b2483 100644 --- a/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/ics20/mod.rs @@ -34,4 +34,4 @@ impl Memo { pub fn forward(forward: ForwardingMemo) -> Self { Self { forward: Some(forward), wasm: None } } -} \ No newline at end of file +} diff --git a/code/xcvm/lib/core/src/transport/ibc/mod.rs b/code/xcvm/lib/core/src/transport/ibc/mod.rs index e5655ef2633..2cf37369ed7 100644 --- a/code/xcvm/lib/core/src/transport/ibc/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/mod.rs @@ -7,9 +7,7 @@ use crate::{ shared::XcPacket, AssetId, NetworkId, }; -use cosmwasm_std::{ - to_binary, Api, BlockInfo, CosmosMsg, IbcEndpoint, StdResult, WasmMsg, -}; +use cosmwasm_std::{to_binary, Api, BlockInfo, CosmosMsg, IbcEndpoint, StdResult, WasmMsg}; use ibc_rs_scale::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; From 2d986987fc6752159905e1d4d7619696b1cca21d Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 14:44:57 +0100 Subject: [PATCH 12/17] fixes to assets --- .../contracts/gateway/src/contract/execute.rs | 2 +- .../gateway/src/contract/ibc/ics20.rs | 29 +++++++++++++++---- code/xcvm/lib/core/src/shared.rs | 7 +++-- code/xcvm/lib/core/src/transport/ibc/mod.rs | 3 +- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index 41bfab5c8af..cb67c87433f 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -48,7 +48,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) let auth = auth::WasmHook::authorise(deps.as_ref(), &env, &info, msg.from_network_id)?; - super::ibc::ics20::ics20_message_hook(auth, msg, env, info) + super::ibc::ics20::ics20_message_hook(auth,deps.as_ref(), msg, env, info) }, msg::ExecuteMsg::Shortcut(msg) => handle_shortcut(deps, env, info, msg), } diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index 8b905879812..53567c5ee89 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -4,14 +4,14 @@ //! handles PFM and IBC wasm hooks use crate::prelude::*; use cosmwasm_std::{ - ensure_eq, wasm_execute, Binary, BlockInfo, Coin, DepsMut, Env, MessageInfo, Response, Storage, - SubMsg, + ensure_eq, wasm_execute, Binary, BlockInfo, Coin, Deps, DepsMut, Env, MessageInfo, Response, + Storage, SubMsg, }; use xc_core::{ gateway::{AssetItem, ExecuteMsg, ExecuteProgramMsg, GatewayId, OtherNetworkItem}, - shared::{XcPacket, XcProgram}, + shared::{XcFunds, XcPacket, XcProgram}, transport::ibc::{to_cw_message, IbcIcs20Route, XcMessageData}, - AssetId, CallOrigin, + AssetId, CallOrigin, Displayed, }; use crate::{ @@ -145,15 +145,34 @@ pub fn get_route( pub(crate) fn ics20_message_hook( _: auth::WasmHook, + deps: Deps, msg: XcMessageData, env: Env, info: MessageInfo, ) -> Result { let packet: XcPacket = msg.packet; ensure_anonymous(&packet.program)?; + + let assets: Result = info + .funds + .into_iter() + .map(|coin| { + match crate::assets::get_local_asset_by_reference( + deps, + AssetReference::Native { denom: coin.denom }, + ) { + Ok(asset) => Ok((asset.asset_id, Displayed::::from(coin.amount.u128()))), + Err(err) => Err(err), + } + }) + .collect(); + deps.api.debug(&format!( + "xcvm::gateway::ibc::ics20:: received assets {:?}, packet assets {:?}", + &assets, &packet.assets + )); let call_origin = CallOrigin::Remote { user_origin: packet.user_origin }; let execute_program = - ExecuteProgramMsg { salt: packet.salt, program: packet.program, assets: packet.assets }; + ExecuteProgramMsg { salt: packet.salt, program: packet.program, assets: assets?.into() }; let msg = ExecuteMsg::ExecuteProgramPrivileged { call_origin, execute_program, tip: info.sender }; let msg = wasm_execute(env.contract.address, &msg, Default::default())?; diff --git a/code/xcvm/lib/core/src/shared.rs b/code/xcvm/lib/core/src/shared.rs index 48fb8773697..ceea34183b2 100644 --- a/code/xcvm/lib/core/src/shared.rs +++ b/code/xcvm/lib/core/src/shared.rs @@ -1,11 +1,12 @@ -use crate::prelude::*; +use crate::{prelude::*, AssetId, Displayed}; use cosmwasm_std::{from_binary, to_binary, Binary, CanonicalAddr, StdResult}; use serde::{de::DeserializeOwned, Serialize}; -pub type XcInstruction = crate::Instruction, CanonicalAddr, crate::Funds>; -pub type XcProgram = crate::Program>; pub type XcPacket = crate::Packet; +pub type XcProgram = crate::Program>; pub type Salt = Vec; +pub type XcInstruction = crate::Instruction, CanonicalAddr, crate::Funds>; +pub type XcFunds = Vec<(AssetId, Displayed)>; pub fn encode_base64(x: &T) -> StdResult { Ok(to_binary(x)?.to_base64()) diff --git a/code/xcvm/lib/core/src/transport/ibc/mod.rs b/code/xcvm/lib/core/src/transport/ibc/mod.rs index 2cf37369ed7..78c0e9ea1ae 100644 --- a/code/xcvm/lib/core/src/transport/ibc/mod.rs +++ b/code/xcvm/lib/core/src/transport/ibc/mod.rs @@ -45,6 +45,7 @@ pub struct IbcIcs20Route { pub local_native_denom: String, pub channel_to_send_over: ChannelId, pub sender_gateway: Addr, + /// the contract address of the gateway to send to assets pub gateway_to_send_to: Addr, pub counterparty_timeout: RelativeTimeout, pub ibc_ics_20_sender: IbcIcs20Sender, @@ -115,7 +116,7 @@ pub fn to_cw_message( .counterparty_timeout .absolute(block) .timestamp() - .map(|x| x.seconds()) + .map(|x| x.nanos()) .unwrap_or_default(), memo, } From 5ad1974787869f2d5af0ee8ab9d10ad9efcd23df Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 14:45:19 +0100 Subject: [PATCH 13/17] assets --- code/xcvm/lib/core/src/shared.rs | 6 +++--- flake/osmosis.nix | 8 ++++---- .../notional-labs/composable-centauri/flake-module.nix | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/code/xcvm/lib/core/src/shared.rs b/code/xcvm/lib/core/src/shared.rs index ceea34183b2..8f80d641570 100644 --- a/code/xcvm/lib/core/src/shared.rs +++ b/code/xcvm/lib/core/src/shared.rs @@ -2,11 +2,11 @@ use crate::{prelude::*, AssetId, Displayed}; use cosmwasm_std::{from_binary, to_binary, Binary, CanonicalAddr, StdResult}; use serde::{de::DeserializeOwned, Serialize}; -pub type XcPacket = crate::Packet; -pub type XcProgram = crate::Program>; pub type Salt = Vec; -pub type XcInstruction = crate::Instruction, CanonicalAddr, crate::Funds>; pub type XcFunds = Vec<(AssetId, Displayed)>; +pub type XcInstruction = crate::Instruction, CanonicalAddr, crate::Funds>; +pub type XcPacket = crate::Packet; +pub type XcProgram = crate::Program>; pub fn encode_base64(x: &T) -> StdResult { Ok(to_binary(x)?.to_base64()) diff --git a/flake/osmosis.nix b/flake/osmosis.nix index 7b24b03e140..f9bd9c83452 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -190,7 +190,7 @@ INSTANTIATE=$(cat << EOF { "admin" : "$KEY", - "here_id" : $NETWORK_ID + "network_id" : $NETWORK_ID } EOF ) @@ -326,7 +326,7 @@ "config": { "force_asset": { "asset_id": "79228162514264337593543950337", - "from_network_id": 2, + "network_id": 2, "local": { "native": { "denom": "ppica" @@ -354,7 +354,7 @@ "config": { "force_asset": { "asset_id": "158456325028528675187087901673", - "from_network_id": 3, + "network_id": 3, "local": { "native": { "denom" : "uosmo" @@ -373,7 +373,7 @@ "config": { "force_asset": { "asset_id": "237684487542793012780631852009", - "from_network_id": 3, + "network_id": 3, "local": { "native": { "denom" : "uosmo" diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index 98b93b0577a..8d29268c87b 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -114,7 +114,7 @@ INSTANTIATE=$(cat << EOF { "admin" : "$KEY", - "here_id" : $NETWORK_ID + "network_id" : $NETWORK_ID } EOF ) @@ -248,7 +248,7 @@ "config": { "force_asset": { "asset_id": "158456325028528675187087900673", - "from_network_id": 2, + "network_id": 2, "local": { "native": { "denom": "ppica" @@ -276,7 +276,7 @@ "config": { "force_asset": { "asset_id": "158456325028528675187087900674", - "from_network_id": 2, + "network_id": 2, "local": { "native": { "denom": "uatom" @@ -304,7 +304,7 @@ "config": { "force_asset": { "asset_id": "237684487542793012780631851009", - "from_network_id": 3, + "network_id": 3, "local": { "native": { "denom": "ppica" @@ -347,7 +347,7 @@ "config": { "force_asset": { "asset_id": "237684487542793012780631851010", - "from_network_id": 2, + "network_id": 2, "local": { "native": { "denom" : "uatom" From 81f10554b4ecb2830358151be6fd1e469fb142ab Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Sun, 13 Aug 2023 18:46:05 +0100 Subject: [PATCH 14/17] works --- code/Cargo.lock | 1 + .../contracts/gateway/src/contract/execute.rs | 9 +- .../gateway/src/contract/ibc/ics20.rs | 8 +- .../contracts/interpreter/src/contract.rs | 2 +- code/xcvm/lib/core/Cargo.toml | 3 + code/xcvm/lib/core/src/cosmos.rs | 29 +++-- code/xcvm/lib/core/src/gateway/mod.rs | 120 ++++++++++++++++++ flake/hermes.toml | 4 +- flake/osmosis.nix | 42 ++++-- .../composable-centauri/flake-module.nix | 99 +++++++++------ 10 files changed, 246 insertions(+), 71 deletions(-) diff --git a/code/Cargo.lock b/code/Cargo.lock index 6d466268c58..f436746eea6 100644 --- a/code/Cargo.lock +++ b/code/Cargo.lock @@ -19216,6 +19216,7 @@ name = "xc-core" version = "0.1.0" dependencies = [ "bech32", + "cosmwasm-orchestrate", "cosmwasm-schema 1.2.5", "cosmwasm-std", "cw-storage-plus", diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index cb67c87433f..52e9001063f 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -18,6 +18,13 @@ use xc_core::{gateway::ConfigSubMsg, CallOrigin, Displayed, Funds, InterpreterOr #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) -> Result { use msg::ExecuteMsg; + let sender = &info.sender; + let canonical_sender = deps.api.addr_canonicalize(sender.as_str())?; + deps.api.debug(&format!( + "xcvm::gateway::execute sender on chain {}, sender cross chain {}", + sender, + &serde_json_wasm::to_string(&canonical_sender)? + )); match msg { ExecuteMsg::Config(msg) => { let auth = auth::Admin::authorise(deps.as_ref(), &info)?; @@ -48,7 +55,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) let auth = auth::WasmHook::authorise(deps.as_ref(), &env, &info, msg.from_network_id)?; - super::ibc::ics20::ics20_message_hook(auth,deps.as_ref(), msg, env, info) + super::ibc::ics20::ics20_message_hook(auth, deps.as_ref(), msg, env, info) }, msg::ExecuteMsg::Shortcut(msg) => handle_shortcut(deps, env, info, msg), } diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index 53567c5ee89..c4d3f3753c5 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -152,6 +152,10 @@ pub(crate) fn ics20_message_hook( ) -> Result { let packet: XcPacket = msg.packet; ensure_anonymous(&packet.program)?; + deps.api.debug(&format!( + "xcvm::gateway::ibc::ics20:: received assets {:?}, packet assets {:?}", + &info.funds, &packet.assets + )); let assets: Result = info .funds @@ -166,10 +170,6 @@ pub(crate) fn ics20_message_hook( } }) .collect(); - deps.api.debug(&format!( - "xcvm::gateway::ibc::ics20:: received assets {:?}, packet assets {:?}", - &assets, &packet.assets - )); let call_origin = CallOrigin::Remote { user_origin: packet.user_origin }; let execute_program = ExecuteProgramMsg { salt: packet.salt, program: packet.program, assets: assets?.into() }; diff --git a/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs b/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs index 09ef59dbe9f..cad231e510a 100644 --- a/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs +++ b/code/xcvm/cosmwasm/contracts/interpreter/src/contract.rs @@ -342,7 +342,7 @@ pub fn interpret_transfer( assets: Funds, ) -> Result { let Config { gateway_address: gateway, .. } = CONFIG.load(deps.storage)?; - + deps.api.debug(&format!("xcvm::interpreter:: transfer to {:?}", &to)); let recipient = match to { Destination::Account(account) => deps.api.addr_humanize(&account)?.into_string(), Destination::Tip => tip.into(), diff --git a/code/xcvm/lib/core/Cargo.toml b/code/xcvm/lib/core/Cargo.toml index 1cb18713125..971d6a817c8 100644 --- a/code/xcvm/lib/core/Cargo.toml +++ b/code/xcvm/lib/core/Cargo.toml @@ -29,6 +29,9 @@ ibc-proto = { workspace = true, default-features = false, features = ["serde", " serde-cw-value = { workspace = true, default-features = false} xcm = { workspace = true, default-features = false, optional = true} +[dev-dependencies] +cosmwasm-orchestrate = { workspace = true } + [build-dependencies] prost-build = { workspace = true } diff --git a/code/xcvm/lib/core/src/cosmos.rs b/code/xcvm/lib/core/src/cosmos.rs index 8102464491e..2ec9c6665ad 100644 --- a/code/xcvm/lib/core/src/cosmos.rs +++ b/code/xcvm/lib/core/src/cosmos.rs @@ -19,8 +19,9 @@ pub fn addess_hash(typ: &str, key: &[u8]) -> [u8; 32] { // takes a transfer message and returns ibc/ // https://ibc.cosmos.network/main/architecture/adr-001-coin-source-tracing.html // so can infer for some chain denom on hops -pub fn hash_denom_trace(unwrapped: &str) -> String { - let digest = Sha256::digest(unwrapped.as_bytes()); +pub fn hash_denom_trace(denom: &PrefixedDenom) -> String { + let denom = denom.to_string(); + let digest = Sha256::digest(denom.as_bytes()); ["ibc/", &hex::encode_upper(digest)].concat() } @@ -31,21 +32,21 @@ mod tests { // 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 = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/1").expect("const")); + assert_eq!(pica, "ibc/71B5DB2263A5A5B160BBA26A307BF5441BDB330534C19A9F551F63D9CC0C3026"); + let pica = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/1").expect("const")); + assert_eq!(pica, "ibc/632DBFDB06584976F1351A66E873BF0F7A19FAA083425FEC9890C90993E5F0A4"); - let pica: String = hash_denom_trace("/transfer/channel-1/ppica"); - assert_eq!(pica, "ibc/661BD30059657725608DF36907F06B70C1FA7A1772FF92AEE1844A3E35A80D63"); + let pica: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/ppica").expect("const")); + assert_eq!(pica, "ibc/6188228DA6C48BB205E30BD8850E2E5ADBD75010B9BF542F7E77A87D9D7DCCB7"); - let pica: String = hash_denom_trace("/transfer/channel-0/ppica"); - assert_eq!(pica, "ibc/F0E228914E0E69E7B5E9231282FE6B7595CF90CB76E7193C6AFDCACDF5E83821"); + let pica: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/ppica").expect("const")); + assert_eq!(pica, "ibc/3262D378E1636BE287EC355990D229DCEB828F0C60ED5049729575E235C60E8B"); - let osmo: String = hash_denom_trace("/transfer/channel-1/uosmo"); - assert_eq!(osmo, "ibc/BCACECE44E39A9009D793D68CC5DF76B402607B1C574379DCB4F3A5D24BC1936"); + let osmo: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/uosmo").expect("const")); + assert_eq!(osmo, "ibc/0471F1C4E7AFD3F07702BEF6DC365268D64570F7C1FDC98EA6098DD6DE59817B"); - let osmo: String = hash_denom_trace("/transfer/channel-0/uosmo"); - assert_eq!(osmo, "ibc/B4511F40A2844906F5940444691EE3AE877E8E0DD8354C8C4D36670A46C5680D"); + let osmo: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/uosmo").expect("const")); + assert_eq!(osmo, "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518"); } } diff --git a/code/xcvm/lib/core/src/gateway/mod.rs b/code/xcvm/lib/core/src/gateway/mod.rs index 82f8f22238d..4a44c11bdd9 100644 --- a/code/xcvm/lib/core/src/gateway/mod.rs +++ b/code/xcvm/lib/core/src/gateway/mod.rs @@ -226,6 +226,9 @@ impl Gateway { #[cfg(test)] mod tests { + use bech32_no_std::FromBase32; + use cosmwasm_std::{to_binary, CanonicalAddr}; + use crate::{ gateway::{ExecuteMsg, ExecuteProgramMsg}, generate_asset_id, @@ -387,6 +390,123 @@ mod tests { assert_eq!(program, expected) } + pub struct OsmosisAddressHandler; + + impl cosmwasm_orchestrate::vm::CosmosAddressHandler for OsmosisAddressHandler { + const PREFIX: &'static str = "osmo"; + } + + + #[test] + fn spawn_with_asset_and_transfer() { + let pica_on_centauri = generate_asset_id(2.into(), 0, 1); + let pica_on_osmosis = generate_asset_id(3.into(), 0, 1); + + let program = ExecuteMsg::ExecuteProgram { + execute_program: ExecuteProgramMsg { + salt: b"spawn_with_asset".to_vec(), + program: XcProgram { + tag: b"spawn_with_asset".to_vec(), + instructions: [Instruction::Spawn { + network: 3.into(), + salt: b"spawn_with_asset".to_vec(), + assets: vec![(pica_on_osmosis, 1_000_000_000u128)].into(), + program: XcProgram { + tag: b"spawn_with_asset".to_vec(), + instructions: [XcInstruction::Transfer { + to: crate::Destination::Account(CanonicalAddr( + to_binary(&addr).unwrap() + )), + assets: crate::Funds(vec![( + pica_on_osmosis, + 1_000_000_000u128.into(), + )]), + }] + .into(), + }, + }] + .into(), + }, + assets: vec![(pica_on_centauri, 1_000_000_000u128)].into(), + }, + tip: Addr::unchecked("centauri12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n"), + }; + + //pica_on_osmosis + + let program = serde_json_wasm::to_string(&program).expect("serde"); + let expected = serde_json_wasm::to_string( + &serde_json_wasm::from_str::( + r#" + { + "execute_program": { + "execute_program": { + "salt": "737061776e5f776974685f6173736574", + "program": { + "tag": "737061776e5f776974685f6173736574", + "instructions": [ + { + "spawn": { + "network": 3, + "salt": "737061776e5f776974685f6173736574", + "assets": [ + [ + "237684487542793012780631851009", + { + "amount": { + "intercept": "1000000000", + "slope": "0" + }, + "is_unit": false + } + ] + ], + "program": { + "tag": "737061776e5f776974685f6173736574", + "instructions": [ + { + "transfer": { + "to": { + "account": "Im9zbW8xeDk5cGt6OG1rN21zbXB0ZWdnODg3d3k0NnZydXNsN2trMHN1ZHZhZjJ1aDJrOHF6N3NwcyI=" + }, + "assets": [ + [ + "237684487542793012780631851009", + { + "amount": { + "intercept": "1000000000", + "slope": "0" + }, + "is_unit": false + } + ] + ] + } + } + ] + } + } + } + ] + }, + "assets": [ + [ + "158456325028528675187087900673", + "1000000000" + ] + ] + }, + "tip": "centauri12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n" + } + } + "#, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!(program, expected) + } + #[test] fn osmosis_spawn_with_asset() { let osmo_on_osmosis = generate_asset_id(3.into(), 0, 1001); diff --git a/flake/hermes.toml b/flake/hermes.toml index 9fc9f9d3c70..234e28d70a0 100644 --- a/flake/hermes.toml +++ b/flake/hermes.toml @@ -43,7 +43,7 @@ max_msg_num = 30 max_tx_size = 2097152 clock_drift = '5s' max_block_time = '30s' -trusting_period = '60s' +trusting_period = '480s' trust_threshold = { numerator = '1', denominator = '3' } type = 'CosmosSdk' address_type = { derivation = 'cosmos' } @@ -67,7 +67,7 @@ max_msg_num = 30 max_tx_size = 2097152 clock_drift = '5s' max_block_time = '30s' -trusting_period = '60s' +trusting_period = '480s' trust_threshold = { numerator = '1', denominator = '3' } type = 'CosmosSdk' address_type = { derivation = 'cosmos' } diff --git a/flake/osmosis.nix b/flake/osmosis.nix index f9bd9c83452..47d05ab2458 100644 --- a/flake/osmosis.nix +++ b/flake/osmosis.nix @@ -45,7 +45,7 @@ } dasel-genesis '.app_state.staking.params.bond_denom' 'uosmo' - dasel-genesis '.app_state.staking.params.unbonding_time' '120s' + dasel-genesis '.app_state.staking.params.unbonding_time' '960s' dasel put --type json --file "$GENESIS" --value "[{},{}]" 'app_state.bank.denom_metadata' dasel-genesis '.app_state.bank.denom_metadata.[0].description' 'Registered denom uion for localosmosis testing' dasel put --type json --file "$GENESIS" --value "[{}]" '.app_state.bank.denom_metadata.[0].denom_units' @@ -301,10 +301,7 @@ "to": 3, "other": { "counterparty_timeout": { - "block" : { - "height": 100000, - "revision": 0 - } + "seconds" : 120 }, "ics_20": { "source" : "channel-0", @@ -320,16 +317,41 @@ "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$FORCE_CENTAURI_TO_OSMOSIS" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" --trace --log_level trace + sleep $BLOCK_SECONDS + FORCE_OSMOSIS_TO_CENTAURI=$(cat << EOF + { + "config": { + "force_network_to_network": { + "from": 3, + "to": 2, + "other": { + "counterparty_timeout": { + "seconds" : 120 + }, + "ics_20": { + "source" : "channel-0", + "sink" : "channel-0" + } + + } + } + } + } + EOF + ) + "$BINARY" tx wasm execute "$GATEWAY_CONTRACT_ADDRESS" "$FORCE_OSMOSIS_TO_CENTAURI" --chain-id="$CHAIN_ID" --node "tcp://localhost:$PORT" --output json --yes --gas 25000000 --fees 920000166"$FEE" --log_level info --keyring-backend test --home "$CHAIN_DATA" --from "$KEY" --keyring-dir "$KEYRING_TEST" --trace --log_level trace + + sleep $BLOCK_SECONDS FORCE_PICA=$(cat << EOF { "config": { "force_asset": { - "asset_id": "79228162514264337593543950337", - "network_id": 2, + "asset_id": "237684487542793012780631851009", + "network_id": 3, "local": { "native": { - "denom": "ppica" + "denom": "ibc/3262D378E1636BE287EC355990D229DCEB828F0C60ED5049729575E235C60E8B" } }, "bridged": { @@ -354,10 +376,10 @@ "config": { "force_asset": { "asset_id": "158456325028528675187087901673", - "network_id": 3, + "network_id": 2, "local": { "native": { - "denom" : "uosmo" + "denom" : "transfer/channel-0/uosmo" } } } diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index 8d29268c87b..f94d44de35b 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -380,46 +380,67 @@ TRANSFER_PICA_TO_OSMOSIS=$(cat << EOF { - "execute_program": { "execute_program": { - "salt": "737061776e5f776974685f6173736574", - "program": { - "tag": "737061776e5f776974685f6173736574", - "instructions": [ - { - "spawn": { - "network": 3, - "salt": "737061776e5f776974685f6173736574", - "assets": [ - [ - "158456325028528675187087900673", - { - "amount": { - "intercept": "1234567890", - "slope": "0" + "execute_program": { + "salt": "737061776e5f776974685f6173736574", + "program": { + "tag": "737061776e5f776974685f6173736574", + "instructions": [ + { + "spawn": { + "network": 3, + "salt": "737061776e5f776974685f6173736574", + "assets": [ + [ + "158456325028528675187087900673", + { + "amount": { + "intercept": "1234567890", + "slope": "0" + }, + "is_unit": false + } + ] + ], + "program": { + "tag": "737061776e5f776974685f6173736574", + "instructions": [ + { + "transfer": { + "to": { + "account": "AB9vNpqXOevUvR5+JDnlljDbHhw=" + }, + "assets": [ + [ + "237684487542793012780631851009", + { + "amount": { + + "intercept": "123456789", + "slope": "0" + }, + "is_unit": false + } + ] + ] + } + } + ] + } + } + } + ] }, - "is_unit": false - } - ] - ], - "program": { - "tag": "737061776e5f776974685f6173736574", - "instructions": [] - } - } - } - ] - }, - "assets": [ - [ - "158456325028528675187087900673", - "1234567890" - ] - ] - }, - "tip": "centauri12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n" - } - } + "assets": [ + [ + "158456325028528675187087900673", + "1234567890" + ] + ] + }, + "tip": "centauri12smx2wdlyttvyzvzg54y2vnqwq2qjatescq89n" + } + } EOF ) @@ -542,7 +563,7 @@ centauri-tx = pkgs.writeShellApplication { name = "centaurid-xcvm-config"; runtimeInputs = devnetTools.withBaseContainerTools - ++ [ centaurid pkgs.jq self'.packages.xc-cw-contracts ]; + ++ [ centaurid pkgs.jq ]; text = '' CHAIN_DATA="${devnet-root-directory}/.centaurid" From 5126c65b0c4aa3e6a5d756413b0ed2ea3500d6b5 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Mon, 14 Aug 2023 12:29:00 +0100 Subject: [PATCH 15/17] clean up --- code/Cargo.lock | 1 - code/xcvm/lib/core/Cargo.toml | 3 - code/xcvm/lib/core/src/cosmos.rs | 18 ++- code/xcvm/lib/core/src/gateway/mod.rs | 16 +-- flake/process-compose.nix | 129 ++++++++++-------- .../composable-centauri/flake-module.nix | 9 +- 6 files changed, 93 insertions(+), 83 deletions(-) diff --git a/code/Cargo.lock b/code/Cargo.lock index f436746eea6..6d466268c58 100644 --- a/code/Cargo.lock +++ b/code/Cargo.lock @@ -19216,7 +19216,6 @@ name = "xc-core" version = "0.1.0" dependencies = [ "bech32", - "cosmwasm-orchestrate", "cosmwasm-schema 1.2.5", "cosmwasm-std", "cw-storage-plus", diff --git a/code/xcvm/lib/core/Cargo.toml b/code/xcvm/lib/core/Cargo.toml index 971d6a817c8..1cb18713125 100644 --- a/code/xcvm/lib/core/Cargo.toml +++ b/code/xcvm/lib/core/Cargo.toml @@ -29,9 +29,6 @@ ibc-proto = { workspace = true, default-features = false, features = ["serde", " serde-cw-value = { workspace = true, default-features = false} xcm = { workspace = true, default-features = false, optional = true} -[dev-dependencies] -cosmwasm-orchestrate = { workspace = true } - [build-dependencies] prost-build = { workspace = true } diff --git a/code/xcvm/lib/core/src/cosmos.rs b/code/xcvm/lib/core/src/cosmos.rs index 2ec9c6665ad..988826f6256 100644 --- a/code/xcvm/lib/core/src/cosmos.rs +++ b/code/xcvm/lib/core/src/cosmos.rs @@ -32,21 +32,27 @@ mod tests { // various devnet channels hashes #[test] fn devnet() { - let pica = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/1").expect("const")); + let pica = + hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/1").expect("const")); assert_eq!(pica, "ibc/71B5DB2263A5A5B160BBA26A307BF5441BDB330534C19A9F551F63D9CC0C3026"); - let pica = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/1").expect("const")); + let pica = + hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/1").expect("const")); assert_eq!(pica, "ibc/632DBFDB06584976F1351A66E873BF0F7A19FAA083425FEC9890C90993E5F0A4"); - let pica: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/ppica").expect("const")); + let pica: String = + hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/ppica").expect("const")); assert_eq!(pica, "ibc/6188228DA6C48BB205E30BD8850E2E5ADBD75010B9BF542F7E77A87D9D7DCCB7"); - let pica: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/ppica").expect("const")); + let pica: String = + hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/ppica").expect("const")); assert_eq!(pica, "ibc/3262D378E1636BE287EC355990D229DCEB828F0C60ED5049729575E235C60E8B"); - let osmo: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/uosmo").expect("const")); + let osmo: String = + hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-1/uosmo").expect("const")); assert_eq!(osmo, "ibc/0471F1C4E7AFD3F07702BEF6DC365268D64570F7C1FDC98EA6098DD6DE59817B"); - let osmo: String = hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/uosmo").expect("const")); + let osmo: String = + hash_denom_trace(&PrefixedDenom::from_str("transfer/channel-0/uosmo").expect("const")); assert_eq!(osmo, "ibc/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518"); } } diff --git a/code/xcvm/lib/core/src/gateway/mod.rs b/code/xcvm/lib/core/src/gateway/mod.rs index 4a44c11bdd9..eb277596a69 100644 --- a/code/xcvm/lib/core/src/gateway/mod.rs +++ b/code/xcvm/lib/core/src/gateway/mod.rs @@ -226,8 +226,7 @@ impl Gateway { #[cfg(test)] mod tests { - use bech32_no_std::FromBase32; - use cosmwasm_std::{to_binary, CanonicalAddr}; + use cosmwasm_std::CanonicalAddr; use crate::{ gateway::{ExecuteMsg, ExecuteProgramMsg}, @@ -390,18 +389,11 @@ mod tests { assert_eq!(program, expected) } - pub struct OsmosisAddressHandler; - - impl cosmwasm_orchestrate::vm::CosmosAddressHandler for OsmosisAddressHandler { - const PREFIX: &'static str = "osmo"; - } - - #[test] fn spawn_with_asset_and_transfer() { let pica_on_centauri = generate_asset_id(2.into(), 0, 1); let pica_on_osmosis = generate_asset_id(3.into(), 0, 1); - + let program = ExecuteMsg::ExecuteProgram { execute_program: ExecuteProgramMsg { salt: b"spawn_with_asset".to_vec(), @@ -415,7 +407,7 @@ mod tests { tag: b"spawn_with_asset".to_vec(), instructions: [XcInstruction::Transfer { to: crate::Destination::Account(CanonicalAddr( - to_binary(&addr).unwrap() + Binary::from_base64("AB9vNpqXOevUvR5+JDnlljDbHhw=").unwrap(), )), assets: crate::Funds(vec![( pica_on_osmosis, @@ -467,7 +459,7 @@ mod tests { { "transfer": { "to": { - "account": "Im9zbW8xeDk5cGt6OG1rN21zbXB0ZWdnODg3d3k0NnZydXNsN2trMHN1ZHZhZjJ1aDJrOHF6N3NwcyI=" + "account": "AB9vNpqXOevUvR5+JDnlljDbHhw=" }, "assets": [ [ diff --git a/flake/process-compose.nix b/flake/process-compose.nix index 7f1726f66bb..eea61ada033 100644 --- a/flake/process-compose.nix +++ b/flake/process-compose.nix @@ -12,8 +12,8 @@ runtimeInputs = devnetTools.withBaseContainerTools; name = "devnet-xc-fresh-background"; text = '' - rm --force --recursive /tmp/composable-devnet - mkdir --parents /tmp/composable-devnet + rm --force --recursive ${devnet-root-directory} + mkdir --parents ${devnet-root-directory} ${pkgs.lib.meta.getExe self'.packages.devnet-xc-background} ''; }; @@ -22,8 +22,8 @@ runtimeInputs = devnetTools.withBaseContainerTools; name = "devnet-xc-dotsama-fresh-background"; text = '' - rm --force --recursive /tmp/composable-devnet - mkdir --parents /tmp/composable-devnet + rm --force --recursive ${devnet-root-directory} + mkdir --parents ${devnet-root-directory} ${pkgs.lib.meta.getExe self'.packages.devnet-xc-dotsama-background} ''; }; @@ -48,8 +48,8 @@ runtimeInputs = devnetTools.withBaseContainerTools; name = "devnet-xc-clean"; text = '' - rm --force --recursive /tmp/composable-devnet - mkdir --parents /tmp/composable-devnet + rm --force --recursive ${devnet-root-directory} + mkdir --parents ${devnet-root-directory} ''; }; @@ -57,8 +57,8 @@ runtimeInputs = devnetTools.withBaseContainerTools; name = "devnet-xc-cosmos-fresh"; text = '' - rm --force --recursive /tmp/composable-devnet - mkdir --parents /tmp/composable-devnet + rm --force --recursive ${devnet-root-directory} + mkdir --parents ${devnet-root-directory} ${pkgs.lib.meta.getExe self'.packages.devnet-xc-cosmos} ''; }; @@ -67,8 +67,8 @@ runtimeInputs = devnetTools.withBaseContainerTools; name = "devnet-xc-fresh"; text = '' - rm --force --recursive /tmp/composable-devnet - mkdir --parents /tmp/composable-devnet + rm --force --recursive ${devnet-root-directory} + mkdir --parents ${devnet-root-directory} ${pkgs.lib.meta.getExe self'.packages.devnet-xc} ''; }; @@ -82,25 +82,31 @@ settings = { processes = { centauri = { - command = self'.packages.centaurid-gen; + command = pkgs.writeShellApplication { + runtimeInputs = devnetTools.withBaseContainerTools; + name = "centauri"; + text = '' + ${pkgs.lib.meta.getExe self'.packages.centaurid-gen} reuse 0 + ''; + }; readiness_probe.http_get = { host = "127.0.0.1"; port = 26657; }; - log_location = "/tmp/composable-devnet/centauri.log"; + log_location = "${devnet-root-directory}/centauri.log"; availability = { restart = "on_failure"; }; }; centauri-init = { command = self'.packages.centaurid-init; depends_on."centauri".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/centauri-init.log"; + log_location = "${devnet-root-directory}/centauri-init.log"; availability = { restart = "on_failure"; }; }; picasso = { command = self'.packages.zombienet-rococo-local-picasso-dev; availability = { restart = "on_failure"; }; - log_location = "/tmp/composable-devnet/picasso.log"; + log_location = "${devnet-root-directory}/picasso.log"; readiness_probe = { initial_delay_seconds = 32; period_seconds = 8; @@ -114,7 +120,7 @@ composable = { command = self'.packages.zombienet-composable-centauri-b; availability = { restart = "on_failure"; }; - log_location = "/tmp/composable-devnet/composable.log"; + log_location = "${devnet-root-directory}/composable.log"; readiness_probe = { initial_delay_seconds = 32; period_seconds = 8; @@ -128,7 +134,7 @@ picasso-centauri-ibc-init = { command = self'.packages.picasso-centauri-ibc-init; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-init.log"; + "${devnet-root-directory}/picasso-centauri-ibc-init.log"; depends_on = { "centauri-init".condition = "process_completed_successfully"; "centauri".condition = "process_healthy"; @@ -139,7 +145,7 @@ picasso-centauri-ibc-connection-init = { command = self'.packages.picasso-centauri-ibc-connection-init; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-connection-init.log"; + "${devnet-root-directory}/picasso-centauri-ibc-connection-init.log"; depends_on = { "picasso-centauri-ibc-init".condition = "process_completed_successfully"; @@ -150,7 +156,7 @@ picasso-centauri-ibc-channels-init = { command = self'.packages.picasso-centauri-ibc-channels-init; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-channels-init.log"; + "${devnet-root-directory}/picasso-centauri-ibc-channels-init.log"; depends_on = { "picasso-centauri-ibc-connection-init".condition = "process_completed_successfully"; @@ -161,7 +167,7 @@ picasso-centauri-ibc-relay = { command = self'.packages.picasso-centauri-ibc-relay; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-relay.log"; + "${devnet-root-directory}/picasso-centauri-ibc-relay.log"; depends_on = { "picasso-centauri-ibc-channels-init".condition = "process_completed_successfully"; @@ -172,7 +178,7 @@ composable-picasso-ibc-init = { command = self'.packages.composable-picasso-ibc-init; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-init.log"; + "${devnet-root-directory}/composable-picasso-ibc-init.log"; depends_on = { "picasso-centauri-ibc-channels-init".condition = "process_completed_successfully"; @@ -183,14 +189,14 @@ }; composable-picasso-ibc-connection-init = { command = '' - HOME="/tmp/composable-devnet/composable-picasso-ibc" + HOME="${devnet-root-directory}/composable-picasso-ibc" export HOME RUST_LOG="hyperspace=info,hyperspace_parachain=debug,hyperspace_cosmos=debug" export RUST_LOG - ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-connection --config-a /tmp/composable-devnet/composable-picasso-ibc/config-chain-a.toml --config-b /tmp/composable-devnet/composable-picasso-ibc/config-chain-b.toml --config-core /tmp/composable-devnet/composable-picasso-ibc/config-core.toml --delay-period 10 + ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-connection --config-a ${devnet-root-directory}/composable-picasso-ibc/config-chain-a.toml --config-b ${devnet-root-directory}/composable-picasso-ibc/config-chain-b.toml --config-core ${devnet-root-directory}/composable-picasso-ibc/config-core.toml --delay-period 10 ''; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-connection-init.log"; + "${devnet-root-directory}/composable-picasso-ibc-connection-init.log"; depends_on = { "composable-picasso-ibc-init".condition = "process_completed_successfully"; @@ -200,14 +206,14 @@ composable-picasso-ibc-channels-init = { command = '' - HOME="/tmp/composable-devnet/composable-picasso-ibc" + HOME="${devnet-root-directory}/composable-picasso-ibc" export HOME RUST_LOG="hyperspace=info,hyperspace_parachain=debug,hyperspace_cosmos=debug" export RUST_LOG - ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-channel --config-a /tmp/composable-devnet/composable-picasso-ibc/config-chain-a.toml --config-b /tmp/composable-devnet/composable-picasso-ibc/config-chain-b.toml --config-core /tmp/composable-devnet/composable-picasso-ibc/config-core.toml --delay-period 10 --port-id transfer --version ics20-1 --order unordered + ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-channel --config-a ${devnet-root-directory}/composable-picasso-ibc/config-chain-a.toml --config-b ${devnet-root-directory}/composable-picasso-ibc/config-chain-b.toml --config-core ${devnet-root-directory}/composable-picasso-ibc/config-core.toml --delay-period 10 --port-id transfer --version ics20-1 --order unordered ''; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-channels-init.log"; + "${devnet-root-directory}/composable-picasso-ibc-channels-init.log"; depends_on = { "composable-picasso-ibc-connection-init".condition = "process_completed_successfully"; @@ -217,7 +223,7 @@ composable-picasso-ibc-relay = { command = self'.packages.composable-picasso-ibc-relay; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-relay.log"; + "${devnet-root-directory}/composable-picasso-ibc-relay.log"; depends_on = { "composable-picasso-ibc-channels-init".condition = "process_completed_successfully"; @@ -233,18 +239,24 @@ settings = { processes = { centauri = { - command = self'.packages.centaurid-gen; + command = pkgs.writeShellApplication { + runtimeInputs = devnetTools.withBaseContainerTools; + name = "centauri"; + text = '' + ${pkgs.lib.meta.getExe self'.packages.centaurid-gen} reuse 0 + ''; + }; readiness_probe.http_get = { host = "127.0.0.1"; port = 26657; }; - log_location = "/tmp/composable-devnet/centauri.log"; + log_location = "${devnet-root-directory}/centauri.log"; availability = { restart = "on_failure"; }; }; centauri-init = { command = self'.packages.centaurid-init; depends_on."centauri".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/centauri-init.log"; + log_location = "${devnet-root-directory}/centauri-init.log"; availability = { restart = "on_failure"; }; }; @@ -254,19 +266,20 @@ host = "127.0.0.1"; port = 36657; }; - log_location = "/tmp/composable-devnet/osmosis.log"; + log_location = "${devnet-root-directory}/osmosis.log"; }; osmosisd-xcvm-init = { command = self'.packages.osmosisd-xcvm-init; depends_on."osmosis".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/osmosisd-xcvm-init.log"; + log_location = + "${devnet-root-directory}/osmosisd-xcvm-init.log"; availability = { restart = "on_failure"; }; }; picasso = { command = self'.packages.zombienet-rococo-local-picasso-dev; availability = { restart = "on_failure"; }; - log_location = "/tmp/composable-devnet/picasso.log"; + log_location = "${devnet-root-directory}/picasso.log"; readiness_probe = { initial_delay_seconds = 32; period_seconds = 8; @@ -280,7 +293,7 @@ composable = { command = self'.packages.zombienet-composable-centauri-b; availability = { restart = "on_failure"; }; - log_location = "/tmp/composable-devnet/composable.log"; + log_location = "${devnet-root-directory}/composable.log"; readiness_probe = { initial_delay_seconds = 32; period_seconds = 8; @@ -300,7 +313,7 @@ "osmosis".condition = "process_healthy"; }; log_location = - "/tmp/composable-devnet/osmosis-centauri-hermes-init.log"; + "${devnet-root-directory}/osmosis-centauri-hermes-init.log"; availability = { restart = "on_failure"; }; }; @@ -311,14 +324,14 @@ "process_completed_successfully"; }; log_location = - "/tmp/composable-devnet/osmosis-centauri-hermes-relay.log"; + "${devnet-root-directory}/osmosis-centauri-hermes-relay.log"; availability = { restart = relay; }; }; picasso-centauri-ibc-init = { command = self'.packages.picasso-centauri-ibc-init; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-init.log"; + "${devnet-root-directory}/picasso-centauri-ibc-init.log"; depends_on = { "centauri-init".condition = "process_completed_successfully"; "centauri".condition = "process_healthy"; @@ -330,7 +343,7 @@ picasso-centauri-ibc-connection-init = { command = self'.packages.picasso-centauri-ibc-connection-init; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-connection-init.log"; + "${devnet-root-directory}/picasso-centauri-ibc-connection-init.log"; depends_on = { "picasso-centauri-ibc-init".condition = "process_completed_successfully"; @@ -341,7 +354,7 @@ picasso-centauri-ibc-channels-init = { command = self'.packages.picasso-centauri-ibc-channels-init; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-channels-init.log"; + "${devnet-root-directory}/picasso-centauri-ibc-channels-init.log"; depends_on = { "picasso-centauri-ibc-connection-init".condition = "process_completed_successfully"; @@ -352,7 +365,7 @@ picasso-centauri-ibc-relay = { command = self'.packages.picasso-centauri-ibc-relay; log_location = - "/tmp/composable-devnet/picasso-centauri-ibc-relay.log"; + "${devnet-root-directory}/picasso-centauri-ibc-relay.log"; depends_on = { "picasso-centauri-ibc-channels-init".condition = "process_completed_successfully"; @@ -363,7 +376,7 @@ composable-picasso-ibc-init = { command = self'.packages.composable-picasso-ibc-init; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-init.log"; + "${devnet-root-directory}/composable-picasso-ibc-init.log"; depends_on = { "picasso-centauri-ibc-channels-init".condition = "process_completed_successfully"; @@ -374,14 +387,14 @@ }; composable-picasso-ibc-connection-init = { command = '' - HOME="/tmp/composable-devnet/composable-picasso-ibc" + HOME="${devnet-root-directory}/composable-picasso-ibc" export HOME RUST_LOG="hyperspace=info,hyperspace_parachain=debug,hyperspace_cosmos=debug" export RUST_LOG - ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-connection --config-a /tmp/composable-devnet/composable-picasso-ibc/config-chain-a.toml --config-b /tmp/composable-devnet/composable-picasso-ibc/config-chain-b.toml --config-core /tmp/composable-devnet/composable-picasso-ibc/config-core.toml --delay-period 10 + ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-connection --config-a ${devnet-root-directory}/composable-picasso-ibc/config-chain-a.toml --config-b ${devnet-root-directory}/composable-picasso-ibc/config-chain-b.toml --config-core ${devnet-root-directory}/composable-picasso-ibc/config-core.toml --delay-period 10 ''; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-connection-init.log"; + "${devnet-root-directory}/composable-picasso-ibc-connection-init.log"; depends_on = { "composable-picasso-ibc-init".condition = "process_completed_successfully"; @@ -391,14 +404,14 @@ composable-picasso-ibc-channels-init = { command = '' - HOME="/tmp/composable-devnet/composable-picasso-ibc" + HOME="${devnet-root-directory}/composable-picasso-ibc" export HOME RUST_LOG="hyperspace=info,hyperspace_parachain=debug,hyperspace_cosmos=debug" export RUST_LOG - ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-channel --config-a /tmp/composable-devnet/composable-picasso-ibc/config-chain-a.toml --config-b /tmp/composable-devnet/composable-picasso-ibc/config-chain-b.toml --config-core /tmp/composable-devnet/composable-picasso-ibc/config-core.toml --delay-period 10 --port-id transfer --version ics20-1 --order unordered + ${self'.packages.hyperspace-composable-rococo-picasso-rococo}/bin/hyperspace create-channel --config-a ${devnet-root-directory}/composable-picasso-ibc/config-chain-a.toml --config-b ${devnet-root-directory}/composable-picasso-ibc/config-chain-b.toml --config-core ${devnet-root-directory}/composable-picasso-ibc/config-core.toml --delay-period 10 --port-id transfer --version ics20-1 --order unordered ''; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-channels-init.log"; + "${devnet-root-directory}/composable-picasso-ibc-channels-init.log"; depends_on = { "composable-picasso-ibc-connection-init".condition = "process_completed_successfully"; @@ -408,7 +421,7 @@ composable-picasso-ibc-relay = { command = self'.packages.composable-picasso-ibc-relay; log_location = - "/tmp/composable-devnet/composable-picasso-ibc-relay.log"; + "${devnet-root-directory}/composable-picasso-ibc-relay.log"; depends_on = { "composable-picasso-ibc-channels-init".condition = "process_completed_successfully"; @@ -429,20 +442,21 @@ host = "127.0.0.1"; port = 26657; }; - log_location = "/tmp/composable-devnet/centauri.log"; + log_location = "${devnet-root-directory}/centauri.log"; availability = { restart = "on_failure"; }; }; centauri-init = { command = self'.packages.centaurid-init; depends_on."centauri".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/centauri-init.log"; + log_location = "${devnet-root-directory}/centauri-init.log"; availability = { restart = "on_failure"; }; }; centauri-xcvm-init = { command = self'.packages.centaurid-xcvm-init; depends_on."centauri".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/centauri-xcvm-init.log"; + log_location = + "${devnet-root-directory}/centauri-xcvm-init.log"; availability = { restart = "on_failure"; }; }; @@ -453,7 +467,7 @@ depends_on."osmosis-xcvm-init".condition = "process_completed_successfully"; log_location = - "/tmp/composable-devnet/centauri-xcvm-config.log"; + "${devnet-root-directory}/centauri-xcvm-config.log"; availability = { restart = "on_failure"; }; }; @@ -463,7 +477,8 @@ "process_completed_successfully"; depends_on."osmosis-xcvm-init".condition = "process_completed_successfully"; - log_location = "/tmp/composable-devnet/osmosis-xcvm-config.log"; + log_location = + "${devnet-root-directory}/osmosis-xcvm-config.log"; availability = { restart = "on_failure"; }; }; @@ -473,12 +488,12 @@ host = "127.0.0.1"; port = 36657; }; - log_location = "/tmp/composable-devnet/osmosis.log"; + log_location = "${devnet-root-directory}/osmosis.log"; }; osmosis-xcvm-init = { command = self'.packages.osmosisd-xcvm-init; depends_on."osmosis".condition = "process_healthy"; - log_location = "/tmp/composable-devnet/osmosis-xcvm-init.log"; + log_location = "${devnet-root-directory}/osmosis-xcvm-init.log"; availability = { restart = "on_failure"; }; }; @@ -489,7 +504,7 @@ "osmosis".condition = "process_healthy"; }; log_location = - "/tmp/composable-devnet/osmosis-centauri-hermes-init.log"; + "${devnet-root-directory}/osmosis-centauri-hermes-init.log"; availability = { restart = "on_failure"; }; }; @@ -500,7 +515,7 @@ "process_completed_successfully"; }; log_location = - "/tmp/composable-devnet/osmosis-centauri-hermes-relay.log"; + "${devnet-root-directory}/osmosis-centauri-hermes-relay.log"; availability = { restart = relay; }; }; }; diff --git a/inputs/notional-labs/composable-centauri/flake-module.nix b/inputs/notional-labs/composable-centauri/flake-module.nix index f94d44de35b..622de7ccc8b 100644 --- a/inputs/notional-labs/composable-centauri/flake-module.nix +++ b/inputs/notional-labs/composable-centauri/flake-module.nix @@ -473,6 +473,8 @@ echo "removing data dir" rm --force --recursive "$CHAIN_DATA" fi + PICA_CHANNEL_ID=''${2-1} + if [[ ! -d "$CHAIN_DATA" ]]; then mkdir --parents "$CHAIN_DATA" mkdir --parents "$CHAIN_DATA/config/gentx" @@ -488,14 +490,13 @@ jq-genesis '.app_state.gov.params.voting_period |= "${gov.voting_period}"' jq-genesis '.app_state.gov.params.max_deposit_period |= "${gov.max_deposit_period}"' - function pica() { + function pica_setup() { jq-genesis '.app_state.transmiddleware.token_infos[0].ibc_denom |= "ibc/632DBFDB06584976F1351A66E873BF0F7A19FAA083425FEC9890C90993E5F0A4"' - jq-genesis '.app_state.transmiddleware.token_infos[0].channel_id |= "channel-0"' + jq-genesis ".app_state.transmiddleware.token_infos[0].channel_id |= \"channel-$PICA_CHANNEL_ID\"" jq-genesis '.app_state.transmiddleware.token_infos[0].native_denom |= "ppica"' jq-genesis '.app_state.transmiddleware.token_infos[0].asset_id |= "1"' } - # disabled until https://github.com/notional-labs/composable-centauri/issues/219 - # pica + pica_setup sed -i 's/keyring-backend = "os"/keyring-backend = "test"/' "$CHAIN_DATA/config/client.toml" sed -i 's/keyring-backend = "os"/keyring-backend = "test"/' "$CHAIN_DATA/config/client.toml" From 6c33107234a22c6936a6715f78c558ba88917b24 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Mon, 14 Aug 2023 14:53:12 +0100 Subject: [PATCH 16/17] Update code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs Co-authored-by: Michal Nazarewicz Signed-off-by: dzmitry-lahoda --- code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index 52e9001063f..fa5f47f6aff 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -51,7 +51,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) }, msg::ExecuteMsg::MessageHook(msg) => { deps.api - .debug(format!("xcvm::gateway::execute::message_hook {:?}", msg).as_str()); + .debug(&format!("xcvm::gateway::execute::message_hook {:?}", msg)); let auth = auth::WasmHook::authorise(deps.as_ref(), &env, &info, msg.from_network_id)?; From a55501f8aba56aed542cdebf19830cd85b6198c0 Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Mon, 14 Aug 2023 15:08:13 +0100 Subject: [PATCH 17/17] fixes --- .../contracts/gateway/src/contract/execute.rs | 3 +- .../gateway/src/contract/ibc/ics20.rs | 28 +++++++------------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs index fa5f47f6aff..8362809c300 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/execute.rs @@ -50,8 +50,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: msg::ExecuteMsg) } }, msg::ExecuteMsg::MessageHook(msg) => { - deps.api - .debug(&format!("xcvm::gateway::execute::message_hook {:?}", msg)); + deps.api.debug(&format!("xcvm::gateway::execute::message_hook {:?}", msg)); let auth = auth::WasmHook::authorise(deps.as_ref(), &env, &info, msg.from_network_id)?; diff --git a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs index c4d3f3753c5..076b9d9ace5 100644 --- a/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs +++ b/code/xcvm/cosmwasm/contracts/gateway/src/contract/ibc/ics20.rs @@ -2,13 +2,13 @@ //! Allows to map asset identifiers, contracts, networks, channels, denominations from, to and on //! each chain via contract storage, precompiles, host extensions. //! handles PFM and IBC wasm hooks -use crate::prelude::*; +use crate::{network, prelude::*}; use cosmwasm_std::{ ensure_eq, wasm_execute, Binary, BlockInfo, Coin, Deps, DepsMut, Env, MessageInfo, Response, Storage, SubMsg, }; use xc_core::{ - gateway::{AssetItem, ExecuteMsg, ExecuteProgramMsg, GatewayId, OtherNetworkItem}, + gateway::{AssetItem, ExecuteMsg, ExecuteProgramMsg, GatewayId}, shared::{XcFunds, XcPacket, XcProgram}, transport::ibc::{to_cw_message, IbcIcs20Route, XcMessageData}, AssetId, CallOrigin, Displayed, @@ -100,20 +100,14 @@ pub fn get_route( this_asset_id: AssetId, ) -> Result { let this = load_this(storage)?; - let other: NetworkItem = state::NETWORK - .load(storage, to) - .map_err(|_| ContractError::UnknownTargetNetwork)?; - let this_to_other: OtherNetworkItem = - state::NETWORK_TO_NETWORK.load(storage, (this.network_id, to)).map_err(|_| { - ContractError::NoConnectionInformationFromThisToOtherNetwork(this.network_id, to) - })?; + let other = network::load_other(storage, to)?; let asset: AssetItem = state::assets::ASSETS .load(storage, this_asset_id) .map_err(|_| ContractError::AssetNotFoundById(this_asset_id))?; let to_asset: AssetId = state::assets::NETWORK_ASSET .load(storage, (this_asset_id, to)) .map_err(|_| ContractError::AssetCannotBeTransferredToNetwork(this_asset_id, to))?; - let gateway_to_send_to = other.gateway.ok_or(ContractError::UnsupportedNetwork)?; + let gateway_to_send_to = other.network.gateway.ok_or(ContractError::UnsupportedNetwork)?; let gateway_to_send_to = match gateway_to_send_to { GatewayId::CosmWasm { contract, .. } => contract, }; @@ -122,7 +116,7 @@ pub fn get_route( GatewayId::CosmWasm { contract, .. } => contract, }; - let channel = this_to_other.ics_20.ok_or(ContractError::ICS20NotFound)?.source; + let channel = other.connection.ics_20.ok_or(ContractError::ICS20NotFound)?.source; Ok(IbcIcs20Route { from_network: this.network_id, @@ -130,7 +124,7 @@ pub fn get_route( channel_to_send_over: channel, gateway_to_send_to, sender_gateway, - counterparty_timeout: this_to_other.counterparty_timeout, + counterparty_timeout: other.connection.counterparty_timeout, ibc_ics_20_sender: this .ibc .ok_or(ContractError::ICS20NotFound)? @@ -157,17 +151,15 @@ pub(crate) fn ics20_message_hook( &info.funds, &packet.assets )); - let assets: Result = info + let assets: Result = info .funds .into_iter() .map(|coin| { - match crate::assets::get_local_asset_by_reference( + let asset = crate::assets::get_local_asset_by_reference( deps, AssetReference::Native { denom: coin.denom }, - ) { - Ok(asset) => Ok((asset.asset_id, Displayed::::from(coin.amount.u128()))), - Err(err) => Err(err), - } + )?; + Ok((asset.asset_id, Displayed::::from(coin.amount.u128()))) }) .collect(); let call_origin = CallOrigin::Remote { user_origin: packet.user_origin };