diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 2e04e462..48c202e1 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -14,12 +14,12 @@ jobs: - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v4.4.0 + uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v4.6.0 with: images: paritytech/trappist - name: Build Docker image - uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 #v4.0.0 + uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 #v4.1.1 with: file: docker/trappist-parachain.dockerfile push: false diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index d9b9cf99..840e29d9 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -13,19 +13,19 @@ jobs: uses: actions/checkout@v3 - name: Log in to Docker Hub - uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v4.4.0 + uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175 # v4.6.0 with: images: paritytech/trappist - name: Build and push Docker image - uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 #v4.0.0 + uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 #v4.1.1 with: file: docker/trappist-parachain.dockerfile push: true diff --git a/pallets/asset-registry/src/lib.rs b/pallets/asset-registry/src/lib.rs index 2ee81829..f5545aed 100644 --- a/pallets/asset-registry/src/lib.rs +++ b/pallets/asset-registry/src/lib.rs @@ -22,8 +22,8 @@ pub mod pallet { use frame_system::pallet_prelude::*; use xcm::latest::{ - Junction::{GeneralIndex, PalletInstance, Parachain}, - Junctions, MultiLocation, + Junction::{AccountId32, AccountKey20, GeneralIndex, PalletInstance}, + MultiLocation, }; #[pallet::pallet] @@ -97,13 +97,7 @@ pub mod pallet { // verify MultiLocation is valid ensure!( - matches!( - asset_multi_location, - MultiLocation { - parents: 1, - interior: Junctions::X3(Parachain(_), PalletInstance(_), GeneralIndex(_)) - } - ), + Self::valid_asset_location(&asset_multi_location), Error::::WrongMultiLocation ); @@ -137,6 +131,31 @@ pub mod pallet { } } + impl Pallet { + //Validates that the location points to an asset (Native, Frame based, Erc20) as described + // in the xcm-format: https://github.com/paritytech/xcm-format#concrete-identifiers + fn valid_asset_location(location: &MultiLocation) -> bool { + let (split_multilocation, last_junction) = location.clone().split_last_interior(); + + let check = matches!( + last_junction, + Some(AccountId32 { .. }) | + Some(AccountKey20 { .. }) | + Some(PalletInstance(_)) | + None + ); + + check | + match last_junction { + Some(GeneralIndex(_)) => { + let penultimate = split_multilocation.last(); + matches!(penultimate, Some(PalletInstance(_))) + }, + _ => false, + } + } + } + impl xcm_primitives::AssetMultiLocationGetter> for Pallet { fn get_asset_multi_location(asset_id: AssetIdOf) -> Option { AssetIdMultiLocation::::get(asset_id) diff --git a/pallets/asset-registry/src/tests.rs b/pallets/asset-registry/src/tests.rs index 2b5271ff..eff1e3a7 100644 --- a/pallets/asset-registry/src/tests.rs +++ b/pallets/asset-registry/src/tests.rs @@ -12,84 +12,190 @@ const STATEMINE_ASSET_MULTI_LOCATION: MultiLocation = MultiLocation { ), }; -#[test] -fn register_reserve_asset_works() { - new_test_ext().execute_with(|| { - assert_ok!(AssetRegistry::register_reserve_asset( - RuntimeOrigin::root(), - LOCAL_ASSET_ID, - STATEMINE_ASSET_MULTI_LOCATION, - )); - - assert_eq!( - AssetIdMultiLocation::::get(LOCAL_ASSET_ID), - Some(STATEMINE_ASSET_MULTI_LOCATION) - ); - assert_eq!( - AssetMultiLocationId::::get(STATEMINE_ASSET_MULTI_LOCATION), - Some(LOCAL_ASSET_ID) - ); - }); -} +mod register_reserve_assest { + use super::*; + + #[test] + fn register_reserve_asset_works() { + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + STATEMINE_ASSET_MULTI_LOCATION, + )); + + assert_eq!( + AssetIdMultiLocation::::get(LOCAL_ASSET_ID), + Some(STATEMINE_ASSET_MULTI_LOCATION) + ); + assert_eq!( + AssetMultiLocationId::::get(STATEMINE_ASSET_MULTI_LOCATION), + Some(LOCAL_ASSET_ID) + ); + }); + } -#[test] -fn cannot_register_unexisting_asset() { - new_test_ext().execute_with(|| { - let unexisting_asset_id = 9999; + #[test] + fn cannot_register_unexisting_asset() { + new_test_ext().execute_with(|| { + let unexisting_asset_id = 9999; - assert_noop!( - AssetRegistry::register_reserve_asset( + assert_noop!( + AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + unexisting_asset_id, + STATEMINE_ASSET_MULTI_LOCATION, + ), + Error::::AssetDoesNotExist + ); + }); + } + + #[test] + fn cannot_double_register() { + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( RuntimeOrigin::root(), - unexisting_asset_id, + LOCAL_ASSET_ID, STATEMINE_ASSET_MULTI_LOCATION, + )); + + assert_noop!( + AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + STATEMINE_ASSET_MULTI_LOCATION, + ), + Error::::AssetAlreadyRegistered + ); + }); + } + + #[test] + fn valid_locations_succced() { + let native_frame_based_currency = + MultiLocation { parents: 1, interior: X2(Parachain(1000), PalletInstance(1)) }; + let multiasset_pallet_instance = MultiLocation { + parents: 1, + interior: X3(Parachain(1000), PalletInstance(1), GeneralIndex(2)), + }; + let relay_native_currency = MultiLocation { parents: 1, interior: Junctions::Here }; + let erc20_frame_sm_asset = MultiLocation { + parents: 1, + interior: X3( + Parachain(1000), + PalletInstance(2), + AccountId32 { network: Some(Rococo), id: [0; 32] }, ), - Error::::AssetDoesNotExist - ); - }); -} + }; + let erc20_ethereum_sm_asset = MultiLocation { + parents: 1, + interior: X2( + Parachain(2000), + AccountKey20 { network: Some(Ethereum { chain_id: 56 }), key: [0; 20] }, + ), + }; -#[test] -fn cannot_double_register() { - new_test_ext().execute_with(|| { - assert_ok!(AssetRegistry::register_reserve_asset( - RuntimeOrigin::root(), - LOCAL_ASSET_ID, - STATEMINE_ASSET_MULTI_LOCATION, - )); - - assert_noop!( - AssetRegistry::register_reserve_asset( + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( RuntimeOrigin::root(), LOCAL_ASSET_ID, - STATEMINE_ASSET_MULTI_LOCATION, + native_frame_based_currency, + )); + }); + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + multiasset_pallet_instance, + )); + }); + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + relay_native_currency, + )); + }); + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + erc20_frame_sm_asset, + )); + }); + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + erc20_ethereum_sm_asset, + )); + }); + } + + #[test] + fn invalid_locations_fail() { + let governance_location = MultiLocation { + parents: 1, + interior: X2( + Parachain(1000), + Plurality { id: BodyId::Executive, part: BodyPart::Voice }, ), - Error::::AssetAlreadyRegistered - ); - }); + }; + let invalid_general_index = + MultiLocation { parents: 1, interior: X2(Parachain(1000), GeneralIndex(1u128)) }; + + new_test_ext().execute_with(|| { + assert_noop!( + AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + governance_location, + ), + Error::::WrongMultiLocation + ); + + assert_noop!( + AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + invalid_general_index, + ), + Error::::WrongMultiLocation + ); + }) + } } -#[test] -fn unregister_reserve_asset_works() { - new_test_ext().execute_with(|| { - assert_ok!(AssetRegistry::register_reserve_asset( - RuntimeOrigin::root(), - LOCAL_ASSET_ID, - STATEMINE_ASSET_MULTI_LOCATION, - )); +mod unregister_reserve_asset { + use super::*; - assert_ok!(AssetRegistry::unregister_reserve_asset(RuntimeOrigin::root(), LOCAL_ASSET_ID)); + #[test] + fn unregister_reserve_asset_works() { + new_test_ext().execute_with(|| { + assert_ok!(AssetRegistry::register_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID, + STATEMINE_ASSET_MULTI_LOCATION, + )); - assert!(AssetIdMultiLocation::::get(LOCAL_ASSET_ID).is_none()); - assert!(AssetMultiLocationId::::get(STATEMINE_ASSET_MULTI_LOCATION).is_none()); - }); -} + assert_ok!(AssetRegistry::unregister_reserve_asset( + RuntimeOrigin::root(), + LOCAL_ASSET_ID + )); + + assert!(AssetIdMultiLocation::::get(LOCAL_ASSET_ID).is_none()); + assert!(AssetMultiLocationId::::get(STATEMINE_ASSET_MULTI_LOCATION).is_none()); + }); + } -#[test] -fn cannot_register_unregistered_asset() { - new_test_ext().execute_with(|| { - assert_noop!( - AssetRegistry::unregister_reserve_asset(RuntimeOrigin::root(), LOCAL_ASSET_ID), - Error::::AssetIsNotRegistered - ); - }); + #[test] + fn cannot_register_unregistered_asset() { + new_test_ext().execute_with(|| { + assert_noop!( + AssetRegistry::unregister_reserve_asset(RuntimeOrigin::root(), LOCAL_ASSET_ID), + Error::::AssetIsNotRegistered + ); + }); + } } diff --git a/runtime/trappist/Cargo.toml b/runtime/trappist/Cargo.toml index 72aeddc1..d48309da 100644 --- a/runtime/trappist/Cargo.toml +++ b/runtime/trappist/Cargo.toml @@ -145,6 +145,7 @@ std = [ "pallet-dex-rpc-runtime-api/std", "pallet-identity/std", "pallet-lockdown-mode/std", + "pallet-preimage/std", "pallet-multisig/std", "pallet-insecure-randomness-collective-flip/std", "pallet-scheduler/std", @@ -194,6 +195,7 @@ runtime-benchmarks = [ "pallet-dex/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-lockdown-mode/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", diff --git a/runtime/trappist/src/lib.rs b/runtime/trappist/src/lib.rs index 8e7e8a95..b12a1a89 100644 --- a/runtime/trappist/src/lib.rs +++ b/runtime/trappist/src/lib.rs @@ -76,7 +76,7 @@ pub use parachains_common::{ use impls::{DealWithFees, LockdownDmpHandler, RuntimeBlackListedCalls, XcmExecutionManager}; use xcm_config::{ - CollatorSelectionUpdateOrigin, RelayLocation, TrustBackedAssetsConvertedConcreteId, + CollatorSelectionUpdateOrigin, RelayLocation, SelfReserve, TrustBackedAssetsConvertedConcreteId, }; // Polkadot imports @@ -742,6 +742,7 @@ mod benches { [pallet_collective, Council] [pallet_democracy, Democracy] [pallet_lockdown_mode, LockdownMode] + [pallet_preimage, Preimage] [pallet_treasury, Treasury] [pallet_assets, Assets] [pallet_dex, Dex] @@ -1136,7 +1137,7 @@ impl_runtime_apis! { fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); + let assets: MultiAssets = (Concrete(SelfReserve::get()), 1_000 * UNITS).into(); let ticket = MultiLocation { parents: 0, interior: Here }; Ok((origin, ticket, assets)) }