diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 35e02e5aa1..7ba02643e9 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -3,12 +3,12 @@ name: Publish draft release on: push: tags: - - "v[0-9]+.[0-9]+.[0-9]+.*" - - "[0-9]+.[0-9]+.[0-9]+.*" + - "*" + workflow_dispatch: jobs: build-runtimes: - runs-on: [self-hosted, linux] + runs-on: ubuntu-latest strategy: matrix: runtime: ["interlay", "kintsugi"] @@ -18,14 +18,11 @@ jobs: - name: Build ${{ matrix.runtime }} runtime id: srtool_build - uses: chevdor/srtool-actions@v0.9.2 + uses: paritytech/srtool-actions@v0.9.3 with: - image: docker.io/interlayhq/srtool - tag: nightly-2022-12-15 package: ${{ matrix.runtime }}-runtime-parachain - runtime_dir: ./parachain/runtime/${{ matrix.runtime }} + runtime_dir: parachain/runtime/${{ matrix.runtime }} chain: ${{ matrix.runtime }} - workdir: ${{ github.workspace }} - name: Store srtool digest to disk run: | echo '${{ steps.srtool_build.outputs.json }}' | jq > ${{ matrix.runtime }}_srtool_output.json @@ -91,7 +88,7 @@ jobs: - name: Available platforms run: echo ${{ steps.buildx.outputs.platforms }} - name: Login to Dockerhub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -122,7 +119,7 @@ jobs: platforms: linux/amd64 publish-draft-release: - runs-on: [self-hosted, linux] + runs-on: ubuntu-latest needs: ["build-runtimes", "build-binary"] steps: - name: Checkout @@ -133,6 +130,7 @@ jobs: - uses: actions/download-artifact@v4 with: path: artifacts + pattern: "!*.dockerbuild" - run: | find ./artifacts diff --git a/Cargo.lock b/Cargo.lock index 382967b5e7..55602344a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7354,7 +7354,7 @@ dependencies = [ [[package]] name = "orml-asset-registry" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "frame-system", @@ -7373,7 +7373,7 @@ dependencies = [ [[package]] name = "orml-oracle" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "frame-system", @@ -7391,7 +7391,7 @@ dependencies = [ [[package]] name = "orml-tokens" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "frame-system", @@ -7407,7 +7407,7 @@ dependencies = [ [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -7426,7 +7426,7 @@ dependencies = [ [[package]] name = "orml-unknown-tokens" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "frame-system", @@ -7441,7 +7441,7 @@ dependencies = [ [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "parity-scale-codec", @@ -7455,7 +7455,7 @@ dependencies = [ [[package]] name = "orml-vesting" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "frame-system", @@ -7470,7 +7470,7 @@ dependencies = [ [[package]] name = "orml-xcm" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "frame-system", @@ -7484,7 +7484,7 @@ dependencies = [ [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "frame-support", "orml-traits", @@ -7498,7 +7498,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack//open-runtime-module-library?rev=ca05423f4f32be1d30765caacdc7d90130f5554a#ca05423f4f32be1d30765caacdc7d90130f5554a" +source = "git+https://github.com/r0gue-io//open-runtime-module-library?branch=master#00f4e142772a0dcf8cf06450c6b53600de413575" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -15650,23 +15650,25 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.22", @@ -15687,9 +15689,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -15697,9 +15699,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -15710,9 +15712,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-instrument" diff --git a/Cargo.toml b/Cargo.toml index 51232b8981..7385c2ad6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -248,16 +248,16 @@ cumulus-client-collator = { git = "https://github.com/paritytech//cumulus", bra cumulus-relay-chain-minimal-node = { git = "https://github.com/paritytech//cumulus", branch = "polkadot-v0.9.42" } [patch."https://github.com/open-web3-stack/open-runtime-module-library"] -orml-asset-registry = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-oracle = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-tokens = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-traits = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-unknown-tokens = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-utilities = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-vesting = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-xcm-support = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-xcm = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } -orml-xtokens = { git = "https://github.com/open-web3-stack//open-runtime-module-library", rev = "ca05423f4f32be1d30765caacdc7d90130f5554a" } +orml-asset-registry = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-oracle = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-tokens = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-traits = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-unknown-tokens = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-utilities = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-vesting = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-xcm-support = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-xcm = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } +orml-xtokens = { git = "https://github.com/r0gue-io//open-runtime-module-library", branch = "master" } [patch."https://github.com/paritytech/frontier"] fc-consensus = { git = "https://github.com/paritytech//frontier", branch = "polkadot-v0.9.42" } diff --git a/parachain/runtime/interlay/rust-toolchain.toml b/parachain/runtime/interlay/rust-toolchain.toml new file mode 100644 index 0000000000..d25de7b7ec --- /dev/null +++ b/parachain/runtime/interlay/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2023-03-01" +components = [ "rustfmt", "rls" ] +targets = [ "wasm32-unknown-unknown" ] diff --git a/parachain/runtime/interlay/src/xcm_config.rs b/parachain/runtime/interlay/src/xcm_config.rs index 1cb0f0e598..890af83ada 100644 --- a/parachain/runtime/interlay/src/xcm_config.rs +++ b/parachain/runtime/interlay/src/xcm_config.rs @@ -7,10 +7,9 @@ use frame_support::{ traits::{Everything, Get, Nothing}, }; use orml_asset_registry::{AssetRegistryTrader, FixedRateAssetRegistryTrader}; -use orml_traits::{ - location::AbsoluteReserveProvider, parameter_type_with_key, FixedConversionRateProvider, MultiCurrency, -}; +use orml_traits::{parameter_type_with_key, FixedConversionRateProvider, MultiCurrency}; use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; +use orml_xtokens::AbsoluteReserveProviderMigrationPhase; use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use runtime_common::Transactless; @@ -198,7 +197,7 @@ impl xcm_executor::Config for XcmConfig { #[cfg(not(feature = "runtime-benchmarks"))] type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = MultiNativeAsset; + type IsReserve = MultiNativeAsset>; type IsTeleporter = Nothing; // no teleportation allowed type Barrier = Barrier; type Weigher = FixedWeightBounds; @@ -432,8 +431,9 @@ impl orml_xtokens::Config for Runtime { type MaxAssetsForTransfer = MaxAssetsForTransfer; type MinXcmFee = ParachainMinFee; type MultiLocationsFilter = Everything; - type ReserveProvider = AbsoluteReserveProvider; + type ReserveProvider = AbsoluteReserveProviderMigrationPhase; type UniversalLocation = UniversalLocation; + type MigrationPhaseUpdateOrigin = EnsureRoot; } #[cfg(feature = "runtime-benchmarks")] diff --git a/parachain/runtime/kintsugi/rust-toolchain.toml b/parachain/runtime/kintsugi/rust-toolchain.toml new file mode 100644 index 0000000000..d25de7b7ec --- /dev/null +++ b/parachain/runtime/kintsugi/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2023-03-01" +components = [ "rustfmt", "rls" ] +targets = [ "wasm32-unknown-unknown" ] diff --git a/parachain/runtime/kintsugi/src/lib.rs b/parachain/runtime/kintsugi/src/lib.rs index b65153bb67..d7034efb79 100644 --- a/parachain/runtime/kintsugi/src/lib.rs +++ b/parachain/runtime/kintsugi/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("kintsugi-parachain"), impl_name: create_runtime_str!("kintsugi-parachain"), authoring_version: 1, - spec_version: 1025006, + spec_version: 1025007, impl_version: 1, transaction_version: 4, apis: RUNTIME_API_VERSIONS, diff --git a/parachain/runtime/kintsugi/src/xcm_config.rs b/parachain/runtime/kintsugi/src/xcm_config.rs index b625e7c8e6..380ddcecfa 100644 --- a/parachain/runtime/kintsugi/src/xcm_config.rs +++ b/parachain/runtime/kintsugi/src/xcm_config.rs @@ -6,10 +6,9 @@ use frame_support::{ traits::{Everything, Get, Nothing}, }; use orml_asset_registry::{AssetRegistryTrader, FixedRateAssetRegistryTrader}; -use orml_traits::{ - location::AbsoluteReserveProvider, parameter_type_with_key, FixedConversionRateProvider, MultiCurrency, -}; +use orml_traits::{parameter_type_with_key, FixedConversionRateProvider, MultiCurrency}; use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; +use orml_xtokens::{AbsoluteReserveProviderMigrationPhase, MigrationPhase}; use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use runtime_common::Transactless; @@ -192,7 +191,7 @@ impl xcm_executor::Config for XcmConfig { #[cfg(not(feature = "runtime-benchmarks"))] type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = MultiNativeAsset; + type IsReserve = MultiNativeAsset>; type IsTeleporter = Nothing; // no teleportation allowed type Barrier = Barrier; type Weigher = FixedWeightBounds; @@ -231,6 +230,31 @@ parameter_types! { pub const ReachableDest: MultiLocation = MultiLocation::parent(); } +// A reserve filter to disable pallet xcm reserve transfers during AHM. The reserve provider used +// in the XcmExecutor isn't catching it for some reason (probably the super outdated xcm version) +pub struct PalletXcmReserveTransferFilterMigrationPhase; +impl frame_support::traits::Contains<(MultiLocation, Vec)> + for PalletXcmReserveTransferFilterMigrationPhase +{ + fn contains((_, assets): &(MultiLocation, Vec)) -> bool { + let migration_phase = orml_xtokens::MigrationStatus::::get(); + match migration_phase { + MigrationPhase::InProgress | MigrationPhase::Completed => assets.iter().any(|asset| { + if let AssetId::Concrete(MultiLocation { + parents: 1, + interior: Junctions::Here, + }) = &asset.id + { + false + } else { + true + } + }), + _ => true, + } + } +} + impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; @@ -241,7 +265,7 @@ impl pallet_xcm::Config for Runtime { type XcmExecuteFilter = Nothing; type XcmExecutor = XcmExecutor; type XcmTeleportFilter = Everything; - type XcmReserveTransferFilter = Everything; + type XcmReserveTransferFilter = PalletXcmReserveTransferFilterMigrationPhase; type Weigher = FixedWeightBounds; type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; @@ -426,8 +450,9 @@ impl orml_xtokens::Config for Runtime { type MaxAssetsForTransfer = MaxAssetsForTransfer; type MinXcmFee = ParachainMinFee; type MultiLocationsFilter = Everything; - type ReserveProvider = AbsoluteReserveProvider; + type ReserveProvider = AbsoluteReserveProviderMigrationPhase; type UniversalLocation = UniversalLocation; + type MigrationPhaseUpdateOrigin = EnsureRoot; } #[cfg(feature = "runtime-benchmarks")] diff --git a/parachain/runtime/runtime-tests/src/relaychain/kusama_cross_chain_transfer.rs b/parachain/runtime/runtime-tests/src/relaychain/kusama_cross_chain_transfer.rs index 0880a03e06..9f95e1999c 100644 --- a/parachain/runtime/runtime-tests/src/relaychain/kusama_cross_chain_transfer.rs +++ b/parachain/runtime/runtime-tests/src/relaychain/kusama_cross_chain_transfer.rs @@ -1,17 +1,24 @@ use crate::relaychain::kusama_test_net::*; use codec::Encode; -use frame_support::assert_ok; -use orml_traits::MultiCurrency; +use frame_support::{assert_noop, assert_ok}; +use orml_traits::{location::Reserve, MultiCurrency}; +use orml_xtokens::{AbsoluteReserveProviderMigrationPhase, MigrationPhase}; use primitives::{ CurrencyId::{ForeignAsset, Token}, CustomMetadata, TokenSymbol, }; +use sp_core::crypto::Ss58Codec; use sp_runtime::{FixedPointNumber, FixedU128}; use xcm::latest::{prelude::*, Weight}; use xcm_builder::ParentIsPreset; use xcm_emulator::{TestExt, XcmExecutor}; use xcm_executor::traits::Convert; +fn sibling_sovereign_account() -> AccountId { + use sp_runtime::traits::AccountIdConversion; + polkadot_parachain::primitives::Sibling::from(SIBLING_PARA_ID).into_account_truncating() +} + mod fees { use super::*; @@ -271,11 +278,6 @@ fn transfer_to_relay_chain() { /// integrated. #[test] fn transfer_to_sibling_and_back() { - fn sibling_sovereign_account() -> AccountId { - use sp_runtime::traits::AccountIdConversion; - polkadot_parachain::primitives::Sibling::from(SIBLING_PARA_ID).into_account_truncating() - } - Sibling::execute_with(|| { register_kint_as_foreign_asset(); }); @@ -691,3 +693,344 @@ fn register_kint_as_foreign_asset() { }; AssetRegistry::register_asset(RuntimeOrigin::root(), metadata, None).unwrap(); } + +// ** ASSET HUB MIGRATION TESTS** +const SIBLING_PARACHAIN: Junction = Parachain(SIBLING_PARA_ID); +const ASSET_HUB: Junction = Parachain(ASSET_HUB_ID); + +fn concrete_fungible(id: MultiLocation) -> MultiAsset { + (id, 1).into() +} +fn register_sibling_asset_as_foreign_asset() { + let metadata = AssetMetadata { + decimals: 8, + name: "kBTC".as_bytes().to_vec(), + symbol: "KBTC".as_bytes().to_vec(), + existential_deposit: 0, + location: Some(MultiLocation::new(1, X1(Parachain(SIBLING_PARA_ID))).into()), + additional: CustomMetadata { + fee_per_second: 1_000_000_000_000, + coingecko_id: "kbtc".as_bytes().to_vec(), + }, + }; + AssetRegistry::register_asset(RuntimeOrigin::root(), metadata, None).unwrap(); +} + +// Test that xtokens transfers are disabled during the AHM, and that the KSM reserve is correct +// both before and after the migration. the patch was introduced here: +// https://github.com/r0gue-io/open-runtime-module-library/blob/master/xtokens/src/lib.rs#L556. +// This function is called by every call on xtokens, so it's enough with testing this out just with +// the transfer method. +#[test] +fn ahm_transfer_of_ksm_via_xtokens() { + let public = sp_core::sr25519::Public::from_ss58check("5Eg2fnsjADUqvPPTJ17bGgphuxi754R7LsCCqPjt7M5MqVKB").unwrap(); + let kintsugi_sovereign_account_on_asset_hub = AccountId::new(public.0); + + let public = sp_core::sr25519::Public::from_ss58check("5Eg2fntJDju46yds4uKzu2zuQssqw7JZWohhLMj6mZZjg2pK").unwrap(); + let sibling_sovereign_account_on_asset_hub = AccountId::new(public.0); + + TestNet::reset(); + // Before the migration => Everything goes as always, transfers are possible and the reserve is + // KSM + KusamaNet::execute_with(|| { + assert_ok!(kusama_runtime::Balances::transfer( + kusama_runtime::RuntimeOrigin::signed(ALICE.into()), + sp_runtime::MultiAddress::Id(kintsugi_sovereign_account_on_kusama()), + 10 * KSM.one() + )); + }); + + // Fund sovereign accounts on AH + AssetHub::execute_with(|| { + assert_ok!(Tokens::deposit( + Token(KINT), + &kintsugi_sovereign_account_on_asset_hub, + 100_000_000_000_000 + )); + assert_ok!(Tokens::deposit( + Token(KSM), + &kintsugi_sovereign_account_on_asset_hub, + 100_000_000_000_000 + )); + assert_ok!(Tokens::deposit( + Token(KINT), + &sibling_sovereign_account_on_asset_hub, + 100_000_000_000_000 + )); + assert_ok!(Tokens::deposit( + Token(KSM), + &sibling_sovereign_account_on_asset_hub, + 100_000_000_000_000 + )); + }); + + Kintsugi::execute_with(|| { + assert_eq!( + AbsoluteReserveProviderMigrationPhase::::reserve(&concrete_fungible(MultiLocation::parent())), + Some(MultiLocation::parent()) + ); + + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(ALICE.into()), + Token(KSM), + KSM.one(), + Box::new( + MultiLocation::new( + 1, + X2( + Junction::Parachain(SIBLING_PARA_ID), + Junction::AccountId32 { id: BOB, network: None } + ) + ) + .into() + ), + WeightLimit::Unlimited + )); + }); + + Sibling::execute_with(|| { + let bob_balance = Tokens::free_balance(Token(KSM), &AccountId::from(BOB)); + + // A little bit less to pay fees + assert!(bob_balance > 0); + assert!(bob_balance < KSM.one()); + }); + + // During the migration the transfer is deactivated + Kintsugi::execute_with(|| { + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::InProgress + )); + + assert_noop!( + XTokens::transfer( + RuntimeOrigin::signed(ALICE.into()), + Token(KSM), + KSM.one(), + Box::new(MultiLocation::new(1, X1(Junction::AccountId32 { id: BOB, network: None })).into()), + WeightLimit::Unlimited + ), + orml_xtokens::Error::::InvalidDest + ); + }); + + // Sibling has Kintsugi runtime anyway, so we need to updatee the migration phase to recognize + // AssetHub as the reserve + Sibling::execute_with(|| { + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::Completed + )); + }); + + // After the migration, the transfer is available again, but the reserve is now KAH + Kintsugi::execute_with(|| { + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::Completed + )); + + assert_eq!( + AbsoluteReserveProviderMigrationPhase::::reserve(&concrete_fungible(MultiLocation::parent())), + Some(MultiLocation::new(1, ASSET_HUB)) + ); + + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(ALICE.into()), + Token(KSM), + KSM.one(), + Box::new( + MultiLocation::new( + 1, + X2( + Junction::Parachain(SIBLING_PARA_ID), + Junction::AccountId32 { id: BOB, network: None } + ) + ) + .into() + ), + WeightLimit::Unlimited + )); + }); + + AssetHub::execute_with(|| { + let kintsugi_balance = Tokens::free_balance(Token(KSM), &kintsugi_sovereign_account_on_asset_hub); + let sibling_balance = Tokens::free_balance(Token(KSM), &sibling_sovereign_account_on_asset_hub); + assert!(kintsugi_balance < 100_000_000_000_000); + assert!(sibling_balance > 100_000_000_000_000); + }); + + Sibling::execute_with(|| { + let bob_balance = Tokens::free_balance(Token(KSM), &AccountId::from(BOB)); + + // A little bit less to pay fees + assert!(bob_balance > KSM.one()); + assert!(bob_balance < 2 * KSM.one()); + }); +} + +// Other tokens aren't affected by the migration +#[test] +fn ahm_transfer_with_xtokens_not_ksm() { + TestNet::reset(); + Kintsugi::execute_with(|| { + register_sibling_asset_as_foreign_asset(); + + assert_ok!(Tokens::deposit( + ForeignAsset(1), + &AccountId::from(ALICE), + 100_000_000_000_000 + )); + }); + + Kintsugi::execute_with(|| { + // Before the migration => transfer works. The reserve is the sibling + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(ALICE.into()), + ForeignAsset(1), + 10_000_000_000_000, + Box::new( + MultiLocation::new( + 1, + X2( + Parachain(SIBLING_PARA_ID), + Junction::AccountId32 { + network: None, + id: BOB.into(), + } + ) + ) + .into() + ), + WeightLimit::Unlimited, + )); + + assert_eq!( + AbsoluteReserveProviderMigrationPhase::::reserve(&concrete_fungible(MultiLocation::new( + 1, + SIBLING_PARACHAIN + ))), + Some(MultiLocation::new(1, SIBLING_PARACHAIN)) + ); + + // During the migration => transfer works. The reserve is still the sibling + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::InProgress + )); + + assert_eq!( + AbsoluteReserveProviderMigrationPhase::::reserve(&concrete_fungible(MultiLocation::new( + 1, + SIBLING_PARACHAIN + ))), + Some(MultiLocation::new(1, SIBLING_PARACHAIN)) + ); + + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(ALICE.into()), + ForeignAsset(1), + 10_000_000_000_000, + Box::new( + MultiLocation::new( + 1, + X2( + Parachain(SIBLING_PARA_ID), + Junction::AccountId32 { + network: None, + id: BOB.into(), + } + ) + ) + .into() + ), + WeightLimit::Unlimited, + )); + + // After the migration => transfer works. The reserve is still the sibling + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::Completed + )); + + assert_eq!( + AbsoluteReserveProviderMigrationPhase::::reserve(&concrete_fungible(MultiLocation::new( + 1, + SIBLING_PARACHAIN + ))), + Some(MultiLocation::new(1, SIBLING_PARACHAIN)) + ); + + assert_ok!(XTokens::transfer( + RuntimeOrigin::signed(ALICE.into()), + ForeignAsset(1), + 10_000_000_000_000, + Box::new( + MultiLocation::new( + 1, + X2( + Parachain(SIBLING_PARA_ID), + Junction::AccountId32 { + network: None, + id: BOB.into(), + } + ) + ) + .into() + ), + WeightLimit::Unlimited, + )); + }); +} + +#[test] +fn ahm_transfer_not_ksm_via_pallet_xcm() { + TestNet::reset(); + Kintsugi::execute_with(|| { + register_sibling_asset_as_foreign_asset(); + + assert_ok!(Tokens::deposit( + ForeignAsset(1), + &AccountId::from(ALICE), + 100_000_000_000_000 + )); + }); + // Before the migration => Everything works + Kintsugi::execute_with(|| { + assert_ok!(PolkadotXcm::reserve_transfer_assets( + RuntimeOrigin::signed(ALICE.into()), + Box::new(MultiLocation::new(1, SIBLING_PARACHAIN).into()), + Box::new(MultiLocation::new(0, X1(Junction::AccountId32 { id: BOB, network: None })).into()), + Box::new(concrete_fungible(MultiLocation::new(1, SIBLING_PARACHAIN)).into()), + 0 + )); + // During the migration the transfer is deactivated + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::InProgress + )); + + assert_ok!(PolkadotXcm::reserve_transfer_assets( + RuntimeOrigin::signed(ALICE.into()), + Box::new(MultiLocation::new(1, SIBLING_PARACHAIN).into()), + Box::new(MultiLocation::new(0, X1(Junction::AccountId32 { id: BOB, network: None })).into()), + Box::new(concrete_fungible(MultiLocation::new(1, SIBLING_PARACHAIN)).into()), + 0 + )); + + // After the migration, the transfer is available again, but the reserve is now KAH + assert_ok!(XTokens::set_migration_phase( + RuntimeOrigin::root(), + MigrationPhase::Completed + )); + + assert_ok!(PolkadotXcm::reserve_transfer_assets( + RuntimeOrigin::signed(ALICE.into()), + Box::new(MultiLocation::new(1, SIBLING_PARACHAIN).into()), + Box::new(MultiLocation::new(0, X1(Junction::AccountId32 { id: BOB, network: None })).into()), + Box::new(concrete_fungible(MultiLocation::new(1, SIBLING_PARACHAIN)).into()), + 0 + )); + }); +} diff --git a/parachain/runtime/runtime-tests/src/relaychain/kusama_test_net.rs b/parachain/runtime/runtime-tests/src/relaychain/kusama_test_net.rs index 8e68f57efb..e4c3b8d4f5 100644 --- a/parachain/runtime/runtime-tests/src/relaychain/kusama_test_net.rs +++ b/parachain/runtime/runtime-tests/src/relaychain/kusama_test_net.rs @@ -10,6 +10,7 @@ pub use primitives::{ use sp_runtime::traits::AccountIdConversion; use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; +pub const ASSET_HUB_ID: u32 = 1_000; pub const KINTSUGI_PARA_ID: u32 = 2092; pub const SIBLING_PARA_ID: u32 = 2001; @@ -41,11 +42,24 @@ decl_test_parachain! { } } +// This isn't the asset hub runtime but we don't care too much about that, we only need to have a +// parachain registered using the AH ID, so the reserve after the AHM exists on the network +decl_test_parachain! { + pub struct AssetHub { + Runtime = kintsugi_runtime_parachain::Runtime, + RuntimeOrigin = kintsugi_runtime_parachain::RuntimeOrigin, + XcmpMessageHandler = kintsugi_runtime_parachain::XcmpQueue, + DmpMessageHandler = kintsugi_runtime_parachain::DmpQueue, + new_ext = para_ext(ASSET_HUB_ID), + } +} + // note: can't use SIBLING_PARA_ID and KINTSUGI_PARA_ID in this macro - we are forced to use raw numbers decl_test_network! { pub struct TestNet { relay_chain = KusamaNet, parachains = vec![ + (1_000, AssetHub), (2092, Kintsugi), (2001, Sibling), ],