diff --git a/integration-tests/bridges/README.md b/integration-tests/bridges/README.md new file mode 100644 index 0000000000..08e4cc0a65 --- /dev/null +++ b/integration-tests/bridges/README.md @@ -0,0 +1,30 @@ +# Bridges Tests for Local Polkadot <> Kusama Bridge + +This folder contains zombienet based integration test for both onchain and offchain bridges code. +The tests are designed to be run manually. + +To start a test, you need to: + +- download latest [zombienet release](https://github.com/paritytech/zombienet/releases) to +`~/local_bridge_testing/bin/zombienet`. + +- build Polkadot binary by running `cargo build -p polkadot --release` command in the +[`polkadot-sdk`](https://github.com/paritytech/polkadot-sdk) repository clone. + +- build Polkadot Parachain binary by running `cargo build -p polkadot-parachain-bin --release` command in the +[`polkadot-sdk`](https://github.com/paritytech/polkadot-sdk) repository clone. + +- ensure that you have [`node`](https://nodejs.org/en) installed. Additionally, we'll need globally installed +`polkadot/api-cli` package (use `yarn global add @polkadot/api-cli` to install it). + +- build Substrate relay by running `cargo build -p substrate-relay --release` command in the +[`parity-bridges-common`](https://github.com/paritytech/parity-bridges-common) repository clone. Copy the binary to `~/local_bridge_testing/bin/substrate-relay`. + +- add the `sudo` pallet to the Polkadot and Kusama runtimes and give sudo rights to Alice. With this change build +the chain spec generator by running `cargo build --release -p chain-spec-generator --features fast-runtime` +command. Copy the binary to `~/local_bridge_testing/bin/chain-spec-generator`. + +- change the `POLKADOT_BINARY` and `POLKADOT_PARACHAIN_BINARY` paths (and ensure that the nearby variables +have correct values) in the `./run-test.sh`. + +After that, you can run `./run-tests.sh ` command. diff --git a/integration-tests/bridges/environments/polkadot-kusama/bridge_hub_kusama_local_network.toml b/integration-tests/bridges/environments/polkadot-kusama/bridge_hub_kusama_local_network.toml new file mode 100644 index 0000000000..e790b90553 --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/bridge_hub_kusama_local_network.toml @@ -0,0 +1,79 @@ +[settings] +node_spawn_timeout = 240 + +[relaychain] +default_command = "{{POLKADOT_BINARY}}" +default_args = ["-lparachain=debug,xcm=trace"] +chain = "kusama-local" +chain_spec_command = "{{CHAIN_SPEC_GEN_BINARY}} {% raw %} {{chainName}} {% endraw %}" + +[[relaychain.nodes]] +name = "alice" +validator = true +rpc_port = 9935 +ws_port = 9945 +balance = 2000000000000 + +[[relaychain.nodes]] +name = "bob" +validator = true +rpc_port = 9936 +ws_port = 9946 +balance = 2000000000000 + +[[relaychain.nodes]] +name = "charlie" +validator = true +rpc_port = 9937 +ws_port = 9947 +balance = 2000000000000 + +[[parachains]] +id = 1000 +chain = "asset-hub-kusama-local" +chain_spec_command = "{{CHAIN_SPEC_GEN_BINARY}} {% raw %} {{chainName}} {% endraw %}" +cumulus_based = true + +[[parachains.collators]] +name = "asset-hub-kusama-collator-1" +rpc_port = 9011 +ws_port = 9010 +command = "{{POLKADOT_PARACHAIN_BINARY}}" +args = [ + "-lparachain=debug,xcm=trace,runtime::bridge-transfer=trace" +] + +[[parachains.collators]] +name = "asset-hub-kusama-collator-2" +command = "{{POLKADOT_PARACHAIN_BINARY}}" +args = [ + "-lparachain=debug,xcm=trace,runtime::bridge-transfer=trace" +] + +[[parachains]] +id = 1002 +chain = "bridge-hub-kusama-local" +chain_spec_command = "{{ENV_PATH}}/generate_bh_spec.sh Polkadot {% raw %} {{chainName}} {% endraw %}" +cumulus_based = true + +# run alice as parachain collator +[[parachains.collators]] +name = "bridge-hub-kusama-collator-1" +validator = true +command = "{{POLKADOT_PARACHAIN_BINARY}}" +rpc_port = 8935 +ws_port = 8945 +args = [ + "-lparachain=debug,runtime::mmr=info,substrate=info,runtime=info,runtime::bridge-hub=trace,runtime::bridge=trace,runtime::bridge-dispatch=trace,bridge=trace,runtime::bridge-messages=trace,xcm=trace" +] + +# run bob as parachain collator +[[parachains.collators]] +name = "bridge-hub-kusama-collator-2" +validator = true +command = "{{POLKADOT_PARACHAIN_BINARY}}" +rpc_port = 8936 +ws_port = 8946 +args = [ + "-lparachain=trace,runtime::mmr=info,substrate=info,runtime=info,runtime::bridge-hub=trace,runtime::bridge=trace,runtime::bridge-dispatch=trace,bridge=trace,runtime::bridge-messages=trace,xcm=trace" +] diff --git a/integration-tests/bridges/environments/polkadot-kusama/bridge_hub_polkadot_local_network.toml b/integration-tests/bridges/environments/polkadot-kusama/bridge_hub_polkadot_local_network.toml new file mode 100644 index 0000000000..d2ec0207a9 --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/bridge_hub_polkadot_local_network.toml @@ -0,0 +1,77 @@ +[settings] +node_spawn_timeout = 240 + +[relaychain] +default_command = "{{POLKADOT_BINARY}}" +default_args = ["-lparachain=debug,xcm=trace"] +chain = "polkadot-local" +chain_spec_command = "{{CHAIN_SPEC_GEN_BINARY}} {% raw %} {{chainName}} {% endraw %}" + +[[relaychain.nodes]] +name = "alice" +validator = true +rpc_port = 9932 +ws_port = 9942 +balance = 2000000000000 + +[[relaychain.nodes]] +name = "bob" +validator = true +rpc_port = 9933 +ws_port = 9943 +balance = 2000000000000 + +[[relaychain.nodes]] +name = "charlie" +validator = true +rpc_port = 9934 +ws_port = 9944 +balance = 2000000000000 + +[[parachains]] +id = 1000 +chain = "asset-hub-polkadot-local" +chain_spec_command = "{{CHAIN_SPEC_GEN_BINARY}} {% raw %} {{chainName}} {% endraw %}" +cumulus_based = true + +[[parachains.collators]] +name = "asset-hub-polkadot-collator-1" +rpc_port = 9911 +ws_port = 9910 +command = "{{POLKADOT_PARACHAIN_BINARY}}" +args = [ + "-lparachain=debug,xcm=trace,runtime::bridge-transfer=trace" +] + +[[parachains.collators]] +name = "asset-hub-polkadot-collator-2" +command = "{{POLKADOT_PARACHAIN_BINARY}}" +args = [ + "-lparachain=debug,xcm=trace,runtime::bridge-transfer=trace" +] + +[[parachains]] +id = 1002 +chain = "bridge-hub-polkadot-local" +chain_spec_command = "{{ENV_PATH}}/generate_bh_spec.sh Kusama {% raw %} {{chainName}} {% endraw %}" +cumulus_based = true + +[[parachains.collators]] +name = "bridge-hub-polkadot-collator-1" +validator = true +command = "{{POLKADOT_PARACHAIN_BINARY}}" +rpc_port = 8933 +ws_port = 8943 +args = [ + "-lparachain=debug,runtime::bridge-hub=trace,runtime::bridge=trace,runtime::bridge-dispatch=trace,bridge=trace,runtime::bridge-messages=trace,xcm=trace" +] + +[[parachains.collators]] +name = "bridge-hub-polkadot-collator-2" +validator = true +command = "{{POLKADOT_PARACHAIN_BINARY}}" +rpc_port = 8934 +ws_port = 8944 +args = [ + "-lparachain=trace,runtime::bridge-hub=trace,runtime::bridge=trace,runtime::bridge-dispatch=trace,bridge=trace,runtime::bridge-messages=trace,xcm=trace" +] diff --git a/integration-tests/bridges/environments/polkadot-kusama/bridges_polkadot_kusama.sh b/integration-tests/bridges/environments/polkadot-kusama/bridges_polkadot_kusama.sh new file mode 100755 index 0000000000..040db39db3 --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/bridges_polkadot_kusama.sh @@ -0,0 +1,385 @@ +#!/bin/bash + +# import common functions +source "$FRAMEWORK_PATH/utils/bridges.sh" + +# Expected sovereign accounts. +# +# Generated by: +# +##[test] +#fn generate_sovereign_accounts() { +# use polkadot_parachain_primitives::primitives::Sibling; +# use sp_core::crypto::Ss58Codec; +# +# parameter_types! { +# pub UniversalLocationAHP: InteriorLocation = [GlobalConsensus(Polkadot), Parachain(1000)].into(); +# pub UniversalLocationAHK: InteriorLocation = [GlobalConsensus(Kusama), Parachain(1000)].into(); +# } +# +# +# println!( +# "GLOBAL_CONSENSUS_POLKADOT_SOVEREIGN_ACCOUNT=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# GlobalConsensusConvertsFor::::convert_location( +# &Location { parents: 2, interior: [GlobalConsensus(Polkadot)].into() } +# ) +# .unwrap() +# ) +# .to_ss58check_with_version(2_u16.into()) +# ); +# +# println!( +# "ASSET_HUB_KUSAMA_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_KUSAMA=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# SiblingParachainConvertsVia::::convert_location(&Location { +# parents: 1, +# interior: [Parachain(1000)].into() +# }) +# .unwrap() +# ) +# .to_ss58check_with_version(2_u16.into()) +# ); +# +# +# println!( +# "GLOBAL_CONSENSUS_KUSAMA_SOVEREIGN_ACCOUNT=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# GlobalConsensusConvertsFor::::convert_location( +# &Location { parents: 2, interior: [GlobalConsensus(Kusama)].into() } +# ) +# .unwrap() +# ) +# .to_ss58check_with_version(0_u16.into()) +# ); +# println!( +# "ASSET_HUB_POLKADOT_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_POLKADOT=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# SiblingParachainConvertsVia::::convert_location(&Location { +# parents: 1, +# interior: [Parachain(1000)].into() +# }) +# .unwrap() +# ) +# .to_ss58check_with_version(0_u16.into()) +# ); +#} +GLOBAL_CONSENSUS_POLKADOT_SOVEREIGN_ACCOUNT="FxqimVubBRPqJ8kTwb3wL7G4q645hEkBEnXPyttLsTrFc5Q" +ASSET_HUB_KUSAMA_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_KUSAMA="FBeL7EFTDeHnuViqaUHUXvhhUusN5FawDmHgfvzF97DXFr3" +GLOBAL_CONSENSUS_KUSAMA_SOVEREIGN_ACCOUNT="14zcUAhP5XypiFQWA3b1AnGKrhZqR4XWUo4deWkwuN5y983G" +ASSET_HUB_POLKADOT_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_POLKADOT="13cKp89SgdtqUngo2WiEijPrQWdHFhzYZLf2TJePKRvExk7o" + +# Expected sovereign accounts for rewards on BridgeHubs. +# +# Generated by: +##[test] +#fn generate_sovereign_accounts_for_rewards() { +# use bp_messages::LaneId; +# use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParams}; +# use sp_core::crypto::Ss58Codec; +# +# println!( +# "ON_BRIDGE_HUB_POLKADOT_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhks_ThisChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( +# LaneId([0, 0, 0, 1]), +# *b"bhks", +# RewardsAccountOwner::ThisChain +# )) +# ) +# .to_ss58check_with_version(0_u16.into()) +# ); +# +# println!( +# "ON_BRIDGE_HUB_POLKADOT_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhks_BridgedChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( +# LaneId([0, 0, 0, 1]), +# *b"bhks", +# RewardsAccountOwner::BridgedChain +# )) +# ) +# .to_ss58check_with_version(0_u16.into()) +# ); +# +# +# println!( +# "ON_BRIDGE_HUB_KUSAMA_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhpd_ThisChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( +# LaneId([0, 0, 0, 1]), +# *b"bhpd", +# RewardsAccountOwner::ThisChain +# )) +# ) +# .to_ss58check_with_version(2_u16.into()) +# ); +# +# println!( +# "ON_BRIDGE_HUB_KUSAMA_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhpd_BridgedChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( +# LaneId([0, 0, 0, 1]), +# *b"bhpd", +# RewardsAccountOwner::BridgedChain +# )) +# ) +# .to_ss58check_with_version(2_u16.into()) +# ); +#} +ON_BRIDGE_HUB_POLKADOT_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhks_ThisChain="13E5fui93Uyua5RtDv2LQj4aVBBHo6YREe3n6CBwYdqNqoxj" +ON_BRIDGE_HUB_POLKADOT_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhks_BridgedChain="13E5fui93Uyua5RtDv2c9kcAbfrVFeeHyJzHe8sn1Ti77Afd" +ON_BRIDGE_HUB_KUSAMA_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhpd_ThisChain="EoQBtnwp4jMtCEpV7C88rKrz6x1qMBh2z74ibGSqtZRnuMM" +ON_BRIDGE_HUB_KUSAMA_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhpd_BridgedChain="EoQBtnwp4jMtCEpV7CPsssT6bdDHuHZmf3aGXxHJiSA4Dz3" + +LANE_ID="00000001" +XCM_VERSION=3 + +AHK_DOT_ED=10000000 +DOT=10000000000 + +AHP_KSM_ED=10000000 +KSM=1000000000000 + +function init_polkadot_kusama() { + local relayer_path=$(ensure_relayer) + + RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ + $relayer_path init-bridge polkadot-to-bridge-hub-kusama \ + --source-host localhost \ + --source-port 9942 \ + --source-version-mode Auto \ + --target-host localhost \ + --target-port 8945 \ + --target-version-mode Auto \ + --target-signer //Alice +} + +function init_kusama_polkadot() { + local relayer_path=$(ensure_relayer) + + RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ + $relayer_path init-bridge kusama-to-bridge-hub-polkadot \ + --source-host localhost \ + --source-port 9945 \ + --source-version-mode Auto \ + --target-host localhost \ + --target-port 8943 \ + --target-version-mode Auto \ + --target-signer //Alice +} + +function run_relay() { + local relayer_path=$(ensure_relayer) + + RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ + $relayer_path relay-headers-and-messages bridge-hub-kusama-bridge-hub-polkadot \ + --polkadot-host localhost \ + --polkadot-port 9942 \ + --polkadot-version-mode Auto \ + --bridge-hub-polkadot-host localhost \ + --bridge-hub-polkadot-port 8943 \ + --bridge-hub-polkadot-version-mode Auto \ + --bridge-hub-polkadot-signer //Charlie \ + --bridge-hub-polkadot-transactions-mortality 4 \ + --kusama-host localhost \ + --kusama-port 9945 \ + --kusama-version-mode Auto \ + --bridge-hub-kusama-host localhost \ + --bridge-hub-kusama-port 8945 \ + --bridge-hub-kusama-version-mode Auto \ + --bridge-hub-kusama-signer //Charlie \ + --bridge-hub-kusama-transactions-mortality 4 \ + --lane "${LANE_ID}" +} + +case "$1" in + run-relay) + init_kusama_polkadot + init_polkadot_kusama + run_relay + ;; + init-asset-hub-polkadot-local) + ensure_polkadot_js_api + # create foreign assets for native Kusama token (governance call on Polkadot) + force_create_foreign_asset \ + "ws://127.0.0.1:9942" \ + "//Alice" \ + 1000 \ + "ws://127.0.0.1:9910" \ + "$(jq --null-input '{ "parents": 2, "interior": { "X1": { "GlobalConsensus": "Kusama" } } }')" \ + "$GLOBAL_CONSENSUS_KUSAMA_SOVEREIGN_ACCOUNT" \ + $AHP_KSM_ED \ + true + # HRMP + open_hrmp_channels \ + "ws://127.0.0.1:9942" \ + "//Alice" \ + 1000 1002 4 524288 + open_hrmp_channels \ + "ws://127.0.0.1:9942" \ + "//Alice" \ + 1002 1000 4 524288 + # set XCM version of remote AssetHubKusama + force_xcm_version \ + "ws://127.0.0.1:9942" \ + "//Alice" \ + 1000 \ + "ws://127.0.0.1:9910" \ + "$(jq --null-input '{ "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Kusama" }, { "Parachain": 1000 } ] } }')" \ + $XCM_VERSION + ;; + init-bridge-hub-polkadot-local) + ensure_polkadot_js_api + # SA of sibling asset hub pays for the execution + transfer_balance \ + "ws://127.0.0.1:8943" \ + "//Alice" \ + "$ASSET_HUB_POLKADOT_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_POLKADOT" \ + $((25 * $DOT)) + # drip SA of lane dedicated to asset hub for paying rewards for delivery + transfer_balance \ + "ws://127.0.0.1:8943" \ + "//Alice" \ + "$ON_BRIDGE_HUB_POLKADOT_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhks_ThisChain" \ + $((25 * $DOT)) + # drip SA of lane dedicated to asset hub for paying rewards for delivery confirmation + transfer_balance \ + "ws://127.0.0.1:8943" \ + "//Alice" \ + "$ON_BRIDGE_HUB_POLKADOT_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhks_BridgedChain" \ + $((25 * $DOT)) + # set XCM version of remote BridgeHubKusama + force_xcm_version \ + "ws://127.0.0.1:9942" \ + "//Alice" \ + 1002 \ + "ws://127.0.0.1:8943" \ + "$(jq --null-input '{ "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Kusama" }, { "Parachain": 1002 } ] } }')" \ + $XCM_VERSION + ;; + init-asset-hub-kusama-local) + ensure_polkadot_js_api + # create foreign assets for native Polkadot token (governance call on Kusama) + force_create_foreign_asset \ + "ws://127.0.0.1:9945" \ + "//Alice" \ + 1000 \ + "ws://127.0.0.1:9010" \ + "$(jq --null-input '{ "parents": 2, "interior": { "X1": { "GlobalConsensus": "Polkadot" } } }')" \ + "$GLOBAL_CONSENSUS_POLKADOT_SOVEREIGN_ACCOUNT" \ + $AHK_DOT_ED \ + true + # HRMP + open_hrmp_channels \ + "ws://127.0.0.1:9945" \ + "//Alice" \ + 1000 1002 4 524288 + open_hrmp_channels \ + "ws://127.0.0.1:9945" \ + "//Alice" \ + 1002 1000 4 524288 + # set XCM version of remote AssetHubPolkadot + force_xcm_version \ + "ws://127.0.0.1:9945" \ + "//Alice" \ + 1000 \ + "ws://127.0.0.1:9010" \ + "$(jq --null-input '{ "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Polkadot" }, { "Parachain": 1000 } ] } }')" \ + $XCM_VERSION + ;; + init-bridge-hub-kusama-local) + # SA of sibling asset hub pays for the execution + transfer_balance \ + "ws://127.0.0.1:8945" \ + "//Alice" \ + "$ASSET_HUB_KUSAMA_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_KUSAMA" \ + $((25 * $KSM)) + # drip SA of lane dedicated to asset hub for paying rewards for delivery + transfer_balance \ + "ws://127.0.0.1:8945" \ + "//Alice" \ + "$ON_BRIDGE_HUB_KUSAMA_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhpd_ThisChain" \ + $((25 * $KSM)) + # drip SA of lane dedicated to asset hub for paying rewards for delivery confirmation + transfer_balance \ + "ws://127.0.0.1:8945" \ + "//Alice" \ + "$ON_BRIDGE_HUB_KUSAMA_SOVEREIGN_ACCOUNT_FOR_LANE_00000001_bhpd_BridgedChain" \ + $((25 * $KSM)) + # set XCM version of remote BridgeHubPolkadot + force_xcm_version \ + "ws://127.0.0.1:9945" \ + "//Alice" \ + 1002 \ + "ws://127.0.0.1:8945" \ + "$(jq --null-input '{ "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Polkadot" }, { "Parachain": 1002 } ] } }')" \ + $XCM_VERSION + ;; + reserve-transfer-assets-from-asset-hub-polkadot-local) + amount=$2 + ensure_polkadot_js_api + # send DOTs to Alice account on AHK + limited_reserve_transfer_assets \ + "ws://127.0.0.1:9910" \ + "//Alice" \ + "$(jq --null-input '{ "V3": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Kusama" }, { "Parachain": 1000 } ] } } }')" \ + "$(jq --null-input '{ "V3": { "parents": 0, "interior": { "X1": { "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } } } } }')" \ + "$(jq --null-input '{ "V3": [ { "id": { "Concrete": { "parents": 1, "interior": "Here" } }, "fun": { "Fungible": '$amount' } } ] }')" \ + 0 \ + "Unlimited" + ;; + withdraw-reserve-assets-from-asset-hub-polkadot-local) + amount=$2 + ensure_polkadot_js_api + # send back some wrappedKSMs to Alice account on AHK + limited_reserve_transfer_assets \ + "ws://127.0.0.1:9910" \ + "//Alice" \ + "$(jq --null-input '{ "V3": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Kusama" }, { "Parachain": 1000 } ] } } }')" \ + "$(jq --null-input '{ "V3": { "parents": 0, "interior": { "X1": { "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } } } } }')" \ + "$(jq --null-input '{ "V3": [ { "id": { "Concrete": { "parents": 2, "interior": { "X1": { "GlobalConsensus": "Kusama" } } } }, "fun": { "Fungible": '$amount' } } ] }')" \ + 0 \ + "Unlimited" + ;; + reserve-transfer-assets-from-asset-hub-kusama-local) + amount=$2 + ensure_polkadot_js_api + # send KSMs to Alice account on AHP + limited_reserve_transfer_assets \ + "ws://127.0.0.1:9010" \ + "//Alice" \ + "$(jq --null-input '{ "V3": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Polkadot" }, { "Parachain": 1000 } ] } } }')" \ + "$(jq --null-input '{ "V3": { "parents": 0, "interior": { "X1": { "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } } } } }')" \ + "$(jq --null-input '{ "V3": [ { "id": { "Concrete": { "parents": 1, "interior": "Here" } }, "fun": { "Fungible": '$amount' } } ] }')" \ + 0 \ + "Unlimited" + ;; + withdraw-reserve-assets-from-asset-hub-kusama-local) + amount=$2 + ensure_polkadot_js_api + # send back some wrappedDOTs to Alice account on AHP + limited_reserve_transfer_assets \ + "ws://127.0.0.1:9010" \ + "//Alice" \ + "$(jq --null-input '{ "V3": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Polkadot" }, { "Parachain": 1000 } ] } } }')" \ + "$(jq --null-input '{ "V3": { "parents": 0, "interior": { "X1": { "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } } } } }')" \ + "$(jq --null-input '{ "V3": [ { "id": { "Concrete": { "parents": 2, "interior": { "X1": { "GlobalConsensus": "Polkadot" } } } }, "fun": { "Fungible": '$amount' } } ] }')" \ + 0 \ + "Unlimited" + ;; + *) + echo "A command is require. Supported commands for: + Local (zombienet) run: + - run-relay + - init-asset-hub-polkadot-local + - init-bridge-hub-polkadot-local + - init-asset-hub-kusama-local + - init-bridge-hub-kusama-local + - reserve-transfer-assets-from-asset-hub-polkadot-local + - withdraw-reserve-assets-from-asset-hub-polkadot-local + - reserve-transfer-assets-from-asset-hub-kusama-local + - withdraw-reserve-assets-from-asset-hub-kusama-local"; + exit 1 + ;; +esac diff --git a/integration-tests/bridges/environments/polkadot-kusama/generate_bh_spec.sh b/integration-tests/bridges/environments/polkadot-kusama/generate_bh_spec.sh new file mode 100755 index 0000000000..b4fcbb8bae --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/generate_bh_spec.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +bridged_chain=$1 +shift + +# Add Alice as bridge owner +# We do this only if there is a `.genesis.runtimeGenesis.patch` object. +# Otherwise we're working with the raw chain spec. +$CHAIN_SPEC_GEN_BINARY "$@" \ + | jq 'if .genesis.runtimeGenesis.patch + then .genesis.runtimeGenesis.patch.bridge'$bridged_chain'Grandpa.owner = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" + else . + end' diff --git a/integration-tests/bridges/environments/polkadot-kusama/helper.sh b/integration-tests/bridges/environments/polkadot-kusama/helper.sh new file mode 100755 index 0000000000..ab48938386 --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/helper.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +$ENV_PATH/bridges_polkadot_kusama.sh "$@" diff --git a/integration-tests/bridges/environments/polkadot-kusama/kusama-bridge.zndsl b/integration-tests/bridges/environments/polkadot-kusama/kusama-bridge.zndsl new file mode 100644 index 0000000000..e2902892aa --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/kusama-bridge.zndsl @@ -0,0 +1,5 @@ +Network: ./bridge_hub_kusama_local_network.toml +Creds: config + +# relay is already started - let's wait until with-Rococo GRANPDA pallet is initialized at Polkadot +bridge-hub-kusama-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/best-finalized-header-at-bridged-chain.js with "Polkadot,0" within 400 seconds diff --git a/integration-tests/bridges/environments/polkadot-kusama/kusama-init.zndsl b/integration-tests/bridges/environments/polkadot-kusama/kusama-init.zndsl new file mode 100644 index 0000000000..4f6bac65af --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/kusama-init.zndsl @@ -0,0 +1,6 @@ +Network: ./bridge_hub_kusama_local_network.toml +Creds: config + +# ensure that initialization has completed +asset-hub-kusama-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/wait-hrmp-channel-opened.js with "1002" within 300 seconds + diff --git a/integration-tests/bridges/environments/polkadot-kusama/polkadot-bridge.zndsl b/integration-tests/bridges/environments/polkadot-kusama/polkadot-bridge.zndsl new file mode 100644 index 0000000000..7dac894542 --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/polkadot-bridge.zndsl @@ -0,0 +1,5 @@ +Network: ./bridge_hub_polkadot_local_network.toml +Creds: config + +# relay is already started - let's wait until with-Rococo GRANPDA pallet is initialized at Polkadot +bridge-hub-polkadot-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/best-finalized-header-at-bridged-chain.js with "Kusama,0" within 400 seconds diff --git a/integration-tests/bridges/environments/polkadot-kusama/polkadot-init.zndsl b/integration-tests/bridges/environments/polkadot-kusama/polkadot-init.zndsl new file mode 100644 index 0000000000..4d7fb281bb --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/polkadot-init.zndsl @@ -0,0 +1,7 @@ +Network: ./bridge_hub_polkadot_local_network.toml +Creds: config + +# ensure that initialization has completed +asset-hub-polkadot-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/wait-hrmp-channel-opened.js with "1002" within 300 seconds + + diff --git a/integration-tests/bridges/environments/polkadot-kusama/spawn.sh b/integration-tests/bridges/environments/polkadot-kusama/spawn.sh new file mode 100755 index 0000000000..3786ce1d4d --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/spawn.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +trap "trap - SIGTERM && kill -9 -$$" SIGINT SIGTERM EXIT + +source "$FRAMEWORK_PATH/utils/zombienet.sh" + +logs_dir=$TEST_DIR/logs +helper_script="${BASH_SOURCE%/*}/helper.sh" + +polkadot_def=${BASH_SOURCE%/*}/bridge_hub_polkadot_local_network.toml +start_zombienet $TEST_DIR $polkadot_def polkadot_dir polkadot_pid +echo + +kusama_def=${BASH_SOURCE%/*}/bridge_hub_kusama_local_network.toml +start_zombienet $TEST_DIR $kusama_def kusama_dir kusama_pid +echo + +polkadot_init_log=$logs_dir/polkadot-init.log +echo -e "Setting up the polkadot side of the bridge. Logs available at: $polkadot_init_log\n" + +kusama_init_log=$logs_dir/kusama-init.log +echo -e "Setting up the kusama side of the bridge. Logs available at: $kusama_init_log\n" + +$helper_script init-asset-hub-polkadot-local >> $polkadot_init_log 2>&1 & +polkadot_init_pid=$! +$helper_script init-asset-hub-kusama-local >> $kusama_init_log 2>&1 & +kusama_init_pid=$! +wait -n $polkadot_init_pid $kusama_init_pid + + +$helper_script init-bridge-hub-polkadot-local >> $polkadot_init_log 2>&1 & +polkadot_init_pid=$! +$helper_script init-bridge-hub-kusama-local >> $kusama_init_log 2>&1 & +kusama_init_pid=$! +wait -n $polkadot_init_pid $kusama_init_pid + +run_zndsl ${BASH_SOURCE%/*}/polkadot-init.zndsl $polkadot_dir +run_zndsl ${BASH_SOURCE%/*}/kusama-init.zndsl $kusama_dir + +${BASH_SOURCE%/*}/start_relayer.sh $polkadot_dir $kusama_dir relayer_pid + +echo $polkadot_dir > $TEST_DIR/polkadot.env +echo $kusama_dir > $TEST_DIR/kusama.env +echo + +wait -n $polkadot_pid $kusama_pid $relayer_pid +kill -9 -$$ diff --git a/integration-tests/bridges/environments/polkadot-kusama/start_relayer.sh b/integration-tests/bridges/environments/polkadot-kusama/start_relayer.sh new file mode 100755 index 0000000000..73e51f99a7 --- /dev/null +++ b/integration-tests/bridges/environments/polkadot-kusama/start_relayer.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e + +source "$FRAMEWORK_PATH/utils/common.sh" +source "$FRAMEWORK_PATH/utils/zombienet.sh" + +polkadot_dir=$1 +kusama_dir=$2 +__relayer_pid=$3 + +logs_dir=$TEST_DIR/logs +helper_script="${BASH_SOURCE%/*}/helper.sh" + +relayer_log=$logs_dir/relayer.log +echo -e "Starting polkadot-kusama relayer. Logs available at: $relayer_log\n" +start_background_process "$helper_script run-relay" $relayer_log relayer_pid + +run_zndsl ${BASH_SOURCE%/*}/polkadot-bridge.zndsl $polkadot_dir +run_zndsl ${BASH_SOURCE%/*}/kusama-bridge.zndsl $kusama_dir + +eval $__relayer_pid="'$relayer_pid'" + diff --git a/integration-tests/bridges/run-test.sh b/integration-tests/bridges/run-test.sh new file mode 100755 index 0000000000..baa542825e --- /dev/null +++ b/integration-tests/bridges/run-test.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -e + +trap 'kill -9 -$$ || echo "Environment already teared down"' SIGINT SIGTERM EXIT + +test=$1 + +export LOCAL_BRIDGE_TESTING_PATH=~/local_bridge_testing +export DOWNLOADS_PATH=$LOCAL_BRIDGE_TESTING_PATH/downloads +mkdir -p $DOWNLOADS_PATH + +# Download the bridge testing "framework" from the `polkadot-sdk` repo +# to `~/local_bridge_testing/downloads/polkadot-sdk`. +framework_repo_path=$DOWNLOADS_PATH/polkadot-sdk +rm -rf $framework_repo_path +git clone --branch master -n --depth=1 --filter=tree:0 \ + https://github.com/paritytech/polkadot-sdk.git $framework_repo_path +pushd $framework_repo_path +git sparse-checkout set --no-cone bridges/testing/framework +git fetch --tags +git checkout polkadot-v1.11.0 +popd +export FRAMEWORK_PATH=$framework_repo_path/bridges/testing/framework +echo + +export ZOMBIENET_BINARY=$LOCAL_BRIDGE_TESTING_PATH/bin/zombienet +export POLKADOT_BINARY=/home/serban/workplace/sources/polkadot-sdk/target/release/polkadot +export POLKADOT_PARACHAIN_BINARY=/home/serban/workplace/sources/polkadot-sdk/target/release/polkadot-parachain +export CHAIN_SPEC_GEN_BINARY=$LOCAL_BRIDGE_TESTING_PATH/bin/chain-spec-generator +export SUBSTRATE_RELAY_BINARY=$LOCAL_BRIDGE_TESTING_PATH/bin/substrate-relay + +export TEST_DIR=`mktemp -d /tmp/bridges-tests-run-XXXXX` +echo -e "Test folder: $TEST_DIR\n" + +${BASH_SOURCE%/*}/tests/$test/run.sh diff --git a/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/dot-reaches-kusama.zndsl b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/dot-reaches-kusama.zndsl new file mode 100644 index 0000000000..13db4cca35 --- /dev/null +++ b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/dot-reaches-kusama.zndsl @@ -0,0 +1,12 @@ +Description: User is able to transfer DOT from Polkadot Asset Hub to Kusama Asset Hub +Network: {{ENV_PATH}}/bridge_hub_kusama_local_network.toml +Creds: config + +# send 5 DOT to //Alice from Polkadot AH to Kusama AH +asset-hub-kusama-collator-1: run {{ENV_PATH}}/helper.sh with "reserve-transfer-assets-from-asset-hub-polkadot-local 50000000000" within 120 seconds + +# check that //Alice received at least 4.8 DOT on Kusama AH +asset-hub-kusama-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,48000000000,Polkadot" within 300 seconds + +# check that the relayer //Charlie is rewarded by Kusama AH +bridge-hub-kusama-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000001,0x62687064,ThisChain,0" within 30 seconds diff --git a/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/ksm-reaches-polkadot.zndsl b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/ksm-reaches-polkadot.zndsl new file mode 100644 index 0000000000..c07bfa9732 --- /dev/null +++ b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/ksm-reaches-polkadot.zndsl @@ -0,0 +1,12 @@ +Description: User is able to transfer KSM from Kusama Asset Hub to Polkadot Asset Hub +Network: {{ENV_PATH}}/bridge_hub_polkadot_local_network.toml +Creds: config + +# send 5 KSM to //Alice from Kusama AH to Polkadot AH +asset-hub-polkadot-collator-1: run {{ENV_PATH}}/helper.sh with "reserve-transfer-assets-from-asset-hub-kusama-local 5000000000000" within 120 seconds + +# check that //Alice received at least 4.8 KSM on Polkadot AH +asset-hub-polkadot-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,4800000000000,Kusama" within 300 seconds + +# check that the relayer //Charlie is rewarded by Polkadot AH +bridge-hub-polkadot-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000001,0x62686b73,ThisChain,0" within 30 seconds diff --git a/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/run.sh b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/run.sh new file mode 100755 index 0000000000..0cfc116119 --- /dev/null +++ b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/run.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Test that checks if asset transfer works on P<>K bridge. +# This test is intentionally not added to the CI. It is meant to be ran manually. + +set -e + +source "$FRAMEWORK_PATH/utils/common.sh" +source "$FRAMEWORK_PATH/utils/zombienet.sh" + +export ENV_PATH=`realpath ${BASH_SOURCE%/*}/../../environments/polkadot-kusama` + +$ENV_PATH/spawn.sh & +env_pid=$! + +ensure_process_file $env_pid $TEST_DIR/polkadot.env 600 +polkadot_dir=`cat $TEST_DIR/polkadot.env` +echo + +ensure_process_file $env_pid $TEST_DIR/kusama.env 300 +kusama_dir=`cat $TEST_DIR/kusama.env` +echo + +run_zndsl ${BASH_SOURCE%/*}/dot-reaches-kusama.zndsl $kusama_dir +run_zndsl ${BASH_SOURCE%/*}/ksm-reaches-polkadot.zndsl $polkadot_dir + +run_zndsl ${BASH_SOURCE%/*}/wdot-reaches-polkadot.zndsl $polkadot_dir +run_zndsl ${BASH_SOURCE%/*}/wksm-reaches-kusama.zndsl $kusama_dir diff --git a/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/wdot-reaches-polkadot.zndsl b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/wdot-reaches-polkadot.zndsl new file mode 100644 index 0000000000..f1546b2a16 --- /dev/null +++ b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/wdot-reaches-polkadot.zndsl @@ -0,0 +1,10 @@ +Description: User is able to transfer wDOT back from Kusama Asset Hub to Polkadot Asset Hub +Network: {{ENV_PATH}}/bridge_hub_polkadot_local_network.toml +Creds: config + +# send 3 wDOT back to Alice from Kusama AH to Polkadot AH +asset-hub-polkadot-collator-1: run {{ENV_PATH}}/helper.sh with "withdraw-reserve-assets-from-asset-hub-kusama-local 30000000000" within 120 seconds + +# check that //Alice received at least 2.8 wDOT on Polkadot AH +# (we wait until //Alice account increases here - there are no other transactions that may increase it) +asset-hub-polkadot-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-assets-balance-increased.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, 28000000000" within 300 seconds diff --git a/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/wksm-reaches-kusama.zndsl b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/wksm-reaches-kusama.zndsl new file mode 100644 index 0000000000..7bb680f080 --- /dev/null +++ b/integration-tests/bridges/tests/0001-polkadot-kusama-asset-transfer/wksm-reaches-kusama.zndsl @@ -0,0 +1,10 @@ +Description: User is able to transfer wKSM from Polkadot Asset Hub back to Kusama Asset Hub +Network: {{ENV_PATH}}/bridge_hub_kusama_local_network.toml +Creds: config + +# send 3 wKSM back to Alice from Polkadot AH to Kusama AH +asset-hub-kusama-collator-1: run {{ENV_PATH}}/helper.sh with "withdraw-reserve-assets-from-asset-hub-polkadot-local 3000000000000" within 120 seconds + +# check that //Alice received at least 2.8 wKSM on Westend AH +# (we wait until //Alice account increases here - there are no other transactions that may increase it) +asset-hub-kusama-collator-1: js-script {{FRAMEWORK_PATH}}/js-helpers/native-assets-balance-increased.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,2800000000000" within 300 seconds