diff --git a/.github/workflows/build-wasm.yml b/.github/workflows/build-wasm.yml index 722c26cc5d..c8441cdd19 100644 --- a/.github/workflows/build-wasm.yml +++ b/.github/workflows/build-wasm.yml @@ -47,7 +47,7 @@ jobs: run: > docker run --rm --user root --platform=linux/amd64 -e PACKAGE=${{ matrix.package }} -v /home/runner/.cargo:/cargo-home - -v ${{ github.workspace }}:/build paritytech/srtool:1.73.0-0.12.0 + -v ${{ github.workspace }}:/build paritytech/srtool:1.75.0-0.14.0 /srtool/build --app # Alternative way of running SRTool that allows for "script-like" execution, diff --git a/Cargo.lock b/Cargo.lock index 44c25cb1c0..43b3ced781 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2450,7 +2450,7 @@ dependencies = [ [[package]] name = "development-runtime" -version = "0.10.41" +version = "0.10.42" dependencies = [ "axelar-gateway-precompile", "cfg-primitives", diff --git a/libs/types/src/tokens.rs b/libs/types/src/tokens.rs index 755d328b41..9feb7b9510 100644 --- a/libs/types/src/tokens.rs +++ b/libs/types/src/tokens.rs @@ -452,7 +452,10 @@ pub mod usdc { pub const CURRENCY_ID_LP_ETH_GOERLI: CurrencyId = CurrencyId::ForeignAsset(100_001); pub const CURRENCY_ID_LP_BASE: CurrencyId = CurrencyId::ForeignAsset(100_002); pub const CURRENCY_ID_LP_ARB: CurrencyId = CurrencyId::ForeignAsset(100_003); - pub const CURRENCY_ID_LP_CELO: CurrencyId = CurrencyId::ForeignAsset(100_004); + + pub const CURRENCY_ID_LP_CELO_WORMHOLE: CurrencyId = CurrencyId::ForeignAsset(100_004); + pub const CURRENCY_ID_LP_CELO: CurrencyId = CurrencyId::ForeignAsset(100_006); + pub const LOCAL_ASSET_ID: LocalAssetId = LocalAssetId(1u32); pub const CURRENCY_ID_LOCAL: CurrencyId = CurrencyId::LocalAsset(LOCAL_ASSET_ID); diff --git a/runtime/altair/src/lib.rs b/runtime/altair/src/lib.rs index cd01ac4a91..d0343753a4 100644 --- a/runtime/altair/src/lib.rs +++ b/runtime/altair/src/lib.rs @@ -251,8 +251,7 @@ impl Contains for BaseCallFilter { RuntimeCall::PolkadotXcm(method) => match method { // Block these calls when called by a signed extrinsic. // Root will still be able to execute these. - pallet_xcm::Call::send { .. } - | pallet_xcm::Call::execute { .. } + pallet_xcm::Call::execute { .. } | pallet_xcm::Call::teleport_assets { .. } | pallet_xcm::Call::reserve_transfer_assets { .. } | pallet_xcm::Call::limited_reserve_transfer_assets { .. } @@ -260,7 +259,9 @@ impl Contains for BaseCallFilter { pallet_xcm::Call::__Ignore { .. } => { unimplemented!() } - pallet_xcm::Call::force_xcm_version { .. } + // Allow all these calls. Only send(..) is callable by signed the rest needs root. + pallet_xcm::Call::send { .. } + | pallet_xcm::Call::force_xcm_version { .. } | pallet_xcm::Call::force_suspension { .. } | pallet_xcm::Call::force_default_xcm_version { .. } | pallet_xcm::Call::force_subscribe_version_notify { .. } diff --git a/runtime/altair/src/xcm.rs b/runtime/altair/src/xcm.rs index 2ef2c9accd..fc2325c177 100644 --- a/runtime/altair/src/xcm.rs +++ b/runtime/altair/src/xcm.rs @@ -27,7 +27,8 @@ use pallet_xcm::XcmPassthrough; use runtime_common::{ transfer_filter::PreXcmTransfer, xcm::{ - general_key, AccountIdToMultiLocation, Barrier, FixedConversionRateProvider, ToTreasury, + general_key, AccountIdToMultiLocation, Barrier, FixedConversionRateProvider, + LocalOriginToLocation, ToTreasury, }, xcm_fees::native_per_second, }; @@ -39,7 +40,7 @@ use xcm::{ use xcm_builder::{ ConvertedConcreteId, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, NoChecking, RelayChainAsNative, SiblingParachainAsNative, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, + SovereignSignedViaLocation, }; use xcm_executor::{traits::JustTry, XcmExecutor}; @@ -170,7 +171,7 @@ impl pallet_xcm::Config for Runtime { type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; type Currency = crate::Balances; type CurrencyMatcher = (); - type ExecuteXcmOrigin = EnsureXcmOrigin; + type ExecuteXcmOrigin = EnsureXcmOrigin>; type MaxLockers = ConstU32<8>; type MaxRemoteLockConsumers = ConstU32<0>; #[cfg(feature = "runtime-benchmarks")] @@ -179,7 +180,7 @@ impl pallet_xcm::Config for Runtime { type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; - type SendXcmOrigin = EnsureXcmOrigin; + type SendXcmOrigin = EnsureXcmOrigin>; type SovereignAccountOf = LocationToAccountId; type TrustedLockers = (); type UniversalLocation = UniversalLocation; @@ -204,9 +205,6 @@ parameter_types! { pub type CurrencyIdConvert = runtime_common::xcm::CurrencyIdConvert; pub type LocationToAccountId = runtime_common::xcm::LocationToAccountId; -/// No local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = SignedToAccountId32; - /// The means for routing XCM messages which are not for local execution /// into the right message queues. pub type XcmRouter = ( diff --git a/runtime/centrifuge/src/lib.rs b/runtime/centrifuge/src/lib.rs index aac3b86a47..33f1a39d56 100644 --- a/runtime/centrifuge/src/lib.rs +++ b/runtime/centrifuge/src/lib.rs @@ -254,8 +254,7 @@ impl Contains for BaseCallFilter { RuntimeCall::PolkadotXcm(method) => match method { // Block these calls when called by a signed extrinsic. // Root will still be able to execute these. - pallet_xcm::Call::send { .. } - | pallet_xcm::Call::execute { .. } + pallet_xcm::Call::execute { .. } | pallet_xcm::Call::teleport_assets { .. } | pallet_xcm::Call::reserve_transfer_assets { .. } | pallet_xcm::Call::limited_reserve_transfer_assets { .. } @@ -263,7 +262,9 @@ impl Contains for BaseCallFilter { pallet_xcm::Call::__Ignore { .. } => { unimplemented!() } - pallet_xcm::Call::force_xcm_version { .. } + // Allow all these calls. Only send(..) is callable by signed the rest needs root. + pallet_xcm::Call::send { .. } + | pallet_xcm::Call::force_xcm_version { .. } | pallet_xcm::Call::force_suspension { .. } | pallet_xcm::Call::force_default_xcm_version { .. } | pallet_xcm::Call::force_subscribe_version_notify { .. } @@ -1802,7 +1803,7 @@ parameter_types! { } impl pallet_order_book::Config for Runtime { - type AdminOrigin = EnsureRoot; + type AdminOrigin = EnsureAccountOrRootOr; type AssetRegistry = OrmlAssetRegistry; type BalanceIn = Balance; type BalanceOut = Balance; diff --git a/runtime/centrifuge/src/migrations.rs b/runtime/centrifuge/src/migrations.rs index 29405b277f..e4c5c7c9a2 100644 --- a/runtime/centrifuge/src/migrations.rs +++ b/runtime/centrifuge/src/migrations.rs @@ -14,7 +14,8 @@ use cfg_primitives::{Balance, PoolId}; use cfg_types::tokens::{ usdc::{ CURRENCY_ID_AXELAR, CURRENCY_ID_DOT_NATIVE, CURRENCY_ID_LOCAL, CURRENCY_ID_LP_ARB, - CURRENCY_ID_LP_BASE, CURRENCY_ID_LP_CELO, CURRENCY_ID_LP_ETH, LOCAL_ASSET_ID, + CURRENCY_ID_LP_BASE, CURRENCY_ID_LP_CELO, CURRENCY_ID_LP_CELO_WORMHOLE, CURRENCY_ID_LP_ETH, + LOCAL_ASSET_ID, }, CurrencyId, LocalAssetId, }; @@ -31,6 +32,7 @@ frame_support::parameter_types! { pub const UsdcEth: CurrencyId = CURRENCY_ID_LP_ETH; pub const UsdcBase: CurrencyId = CURRENCY_ID_LP_BASE; pub const UsdcArb: CurrencyId = CURRENCY_ID_LP_ARB; + pub const UsdcCeloWormhole: CurrencyId = CURRENCY_ID_LP_CELO_WORMHOLE; pub const UsdcCelo: CurrencyId = CURRENCY_ID_LP_CELO; pub const MinOrderAmount: Balance = 10u128.pow(6); pub const AnnualTreasuryInflationPercent: u32 = 3; @@ -51,6 +53,8 @@ pub type UpgradeCentrifuge1025 = ( super::Runtime, LocalCurrencyIdUsdc, >, + // Register new canonical USDC on Celo + runtime_common::migrations::update_celo_usdcs::Migration, // Init local representation for all assets runtime_common::migrations::local_currency::translate_metadata::Migration< super::Runtime, diff --git a/runtime/centrifuge/src/xcm.rs b/runtime/centrifuge/src/xcm.rs index 4ecafe7b1a..aecb26043b 100644 --- a/runtime/centrifuge/src/xcm.rs +++ b/runtime/centrifuge/src/xcm.rs @@ -29,7 +29,7 @@ use runtime_common::{ transfer_filter::PreXcmTransfer, xcm::{ general_key, AccountIdToMultiLocation, Barrier, FixedConversionRateProvider, - LpInstanceRelayer, ToTreasury, + LocalOriginToLocation, LpInstanceRelayer, ToTreasury, }, xcm_fees::native_per_second, }; @@ -41,7 +41,7 @@ use xcm::{ use xcm_builder::{ ConvertedConcreteId, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, NoChecking, RelayChainAsNative, SiblingParachainAsNative, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, + SovereignSignedViaLocation, }; use xcm_executor::{traits::JustTry, XcmExecutor}; @@ -172,7 +172,7 @@ impl pallet_xcm::Config for Runtime { type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; type Currency = crate::Balances; type CurrencyMatcher = (); - type ExecuteXcmOrigin = EnsureXcmOrigin; + type ExecuteXcmOrigin = EnsureXcmOrigin>; type MaxLockers = ConstU32<8>; type MaxRemoteLockConsumers = ConstU32<0>; #[cfg(feature = "runtime-benchmarks")] @@ -181,7 +181,7 @@ impl pallet_xcm::Config for Runtime { type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; - type SendXcmOrigin = EnsureXcmOrigin; + type SendXcmOrigin = EnsureXcmOrigin>; type SovereignAccountOf = LocationToAccountId; type TrustedLockers = (); type UniversalLocation = UniversalLocation; @@ -206,9 +206,6 @@ parameter_types! { pub type CurrencyIdConvert = runtime_common::xcm::CurrencyIdConvert; pub type LocationToAccountId = runtime_common::xcm::LocationToAccountId; -/// No local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = SignedToAccountId32; - /// The means for routing XCM messages which are not for local execution /// into the right message queues. pub type XcmRouter = ( diff --git a/runtime/common/src/migrations/mod.rs b/runtime/common/src/migrations/mod.rs index 95068e9243..791ab2cf44 100644 --- a/runtime/common/src/migrations/mod.rs +++ b/runtime/common/src/migrations/mod.rs @@ -19,3 +19,119 @@ pub mod nuke; pub mod orml_tokens; pub mod precompile_account_codes; pub mod transfer_allowlist_currency; + +pub mod update_celo_usdcs { + use cfg_primitives::Balance; + #[cfg(feature = "try-runtime")] + use cfg_types::tokens::LocalAssetId; + use cfg_types::tokens::{ + usdc::{CURRENCY_ID_LP_CELO, CURRENCY_ID_LP_CELO_WORMHOLE}, + CrossChainTransferability, CurrencyId, CustomMetadata, + }; + use frame_support::{traits::OnRuntimeUpgrade, weights::Weight}; + use hex_literal::hex; + use orml_traits::asset_registry::{AssetMetadata, Mutate}; + use sp_runtime::traits::Get; + #[cfg(feature = "try-runtime")] + use sp_std::{vec, vec::Vec}; + use xcm::v3::{ + Junction::{AccountKey20, GlobalConsensus, PalletInstance}, + Junctions::X3, + NetworkId::Ethereum, + }; + + const LOG_PREFIX: &str = "UpdateCeloUsdcs"; + + pub struct Migration(sp_std::marker::PhantomData); + + impl OnRuntimeUpgrade for Migration + where + T: orml_asset_registry::Config< + CustomMetadata = CustomMetadata, + AssetId = CurrencyId, + Balance = Balance, + >, + { + fn on_runtime_upgrade() -> Weight { + as Mutate>::register_asset( + Some(CURRENCY_ID_LP_CELO), + AssetMetadata { + decimals: 6, + name: "LP Celo Wrapped USDC ".as_bytes().to_vec(), + symbol: "LpCeloUSDC".as_bytes().to_vec(), + existential_deposit: 1000u128, + location: Some( + X3( + PalletInstance(103), + GlobalConsensus(Ethereum { chain_id: 42220 }), + AccountKey20 { + // https://www.circle.com/blog/usdc-now-available-on-celo + key: hex!("cebA9300f2b948710d2653dD7B07f33A8B32118C"), + network: None, + }, + ) + .into(), + ), + additional: CustomMetadata { + transferability: CrossChainTransferability::LiquidityPools, + mintable: false, + permissioned: false, + pool_currency: true, + local_representation: None, + }, + }, + ) + .map_err(|e| { + log::error!( + "{LOG_PREFIX} Failed to register new canonical Celo USDC due to error {:?}", + e + ); + }) + .ok(); + + log::info!("{LOG_PREFIX} Done registering new canonical Celo USDC currency"); + + as Mutate>::update_asset( + CURRENCY_ID_LP_CELO_WORMHOLE, + None, + Some("LP Celo Wrapped Wormhole USDC ".as_bytes().to_vec()), + Some("LpCeloWormUSDC ".as_bytes().to_vec()), + None, + None, + None, + ) + .map_err(|e| { + log::error!( + "{LOG_PREFIX} Failed to update wormhole Celo USDC due to error {:?}", + e + ); + }) + .ok(); + + log::info!("{LOG_PREFIX} Done updating wormhole Celo USDC currency"); + + T::DbWeight::get().writes(2) + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::DispatchError> { + assert!(!orml_asset_registry::Metadata::::contains_key( + CURRENCY_ID_LP_CELO + )); + + log::info!("{LOG_PREFIX} PRE UPGRADE: Finished"); + + Ok(vec![]) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_: Vec) -> Result<(), sp_runtime::DispatchError> { + assert!(orml_asset_registry::Metadata::::contains_key( + CURRENCY_ID_LP_CELO + )); + + log::info!("{LOG_PREFIX} POST UPGRADE: Finished"); + Ok(()) + } + } +} diff --git a/runtime/common/src/xcm.rs b/runtime/common/src/xcm.rs index 9ad03259ae..4699dae850 100644 --- a/runtime/common/src/xcm.rs +++ b/runtime/common/src/xcm.rs @@ -19,20 +19,20 @@ use cfg_types::{ }; use frame_support::{ sp_std::marker::PhantomData, - traits::{fungibles::Mutate, Everything}, + traits::{fungibles::Mutate, Everything, Get}, }; use polkadot_parachain::primitives::Sibling; -use sp_runtime::traits::{AccountIdConversion, Convert}; +use sp_runtime::traits::{AccountIdConversion, Convert, Zero}; use xcm::v3::{ prelude::*, Junction::{AccountId32, AccountKey20, GeneralKey, Parachain}, Junctions::{X1, X2}, - MultiAsset, MultiLocation, OriginKind, + MultiAsset, MultiLocation, NetworkId, OriginKind, }; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, - AllowTopLevelPaidExecutionFrom, ParentIsPreset, SiblingParachainConvertsVia, TakeRevenue, - TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, ParentIsPreset, SiblingParachainConvertsVia, + SignedToAccountId32, TakeRevenue, TakeWeightCredit, }; use crate::xcm_fees::default_per_second; @@ -130,6 +130,27 @@ where } } +/// No local origins on this chain are allowed to dispatch XCM sends/executions. +pub type LocalOriginToLocation = SignedToAccountId32< + ::RuntimeOrigin, + AccountId, + NetworkIdByGenesis, +>; + +pub struct NetworkIdByGenesis(sp_std::marker::PhantomData); + +impl Get> for NetworkIdByGenesis +where + ::Hash: Into<[u8; 32]>, +{ + fn get() -> Option { + Some(NetworkId::ByGenesis( + frame_system::BlockHash::::get(::BlockNumber::zero()) + .into(), + )) + } +} + /// CurrencyIdConvert /// This type implements conversions from our `CurrencyId` type into /// `MultiLocation` and vice-versa. A currency locally is identified with a diff --git a/runtime/development/Cargo.toml b/runtime/development/Cargo.toml index 45286c5770..bd1983ea42 100644 --- a/runtime/development/Cargo.toml +++ b/runtime/development/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "development-runtime" -version = "0.10.41" +version = "0.10.42" build = "build.rs" authors.workspace = true edition.workspace = true diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index cbc800d969..797fa8b8af 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -157,7 +157,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("centrifuge-devel"), impl_name: create_runtime_str!("centrifuge-devel"), authoring_version: 1, - spec_version: 1041, + spec_version: 1042, impl_version: 1, #[cfg(not(feature = "disable-runtime-api"))] apis: RUNTIME_API_VERSIONS, @@ -259,8 +259,7 @@ impl Contains for BaseCallFilter { RuntimeCall::PolkadotXcm(method) => match method { // Block these calls when called by a signed extrinsic. // Root will still be able to execute these. - pallet_xcm::Call::send { .. } - | pallet_xcm::Call::execute { .. } + pallet_xcm::Call::execute { .. } | pallet_xcm::Call::teleport_assets { .. } | pallet_xcm::Call::reserve_transfer_assets { .. } | pallet_xcm::Call::limited_reserve_transfer_assets { .. } @@ -268,7 +267,9 @@ impl Contains for BaseCallFilter { pallet_xcm::Call::__Ignore { .. } => { unimplemented!() } - pallet_xcm::Call::force_xcm_version { .. } + // Allow all these calls. Only send(..) is callable by signed the rest needs root. + pallet_xcm::Call::send { .. } + | pallet_xcm::Call::force_xcm_version { .. } | pallet_xcm::Call::force_suspension { .. } | pallet_xcm::Call::force_default_xcm_version { .. } | pallet_xcm::Call::force_subscribe_version_notify { .. } @@ -2038,7 +2039,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - crate::migrations::UpgradeDevelopment1041, + crate::migrations::UpgradeDevelopment1042, >; // Frame Order in this block dictates the index of each one in the metadata diff --git a/runtime/development/src/migrations.rs b/runtime/development/src/migrations.rs index 52b98c8e00..bf56c19a45 100644 --- a/runtime/development/src/migrations.rs +++ b/runtime/development/src/migrations.rs @@ -23,7 +23,7 @@ frame_support::parameter_types! { pub const AnnualTreasuryInflationPercent: u32 = 3; } -pub type UpgradeDevelopment1041 = ( +pub type UpgradeDevelopment1042 = ( // Register LocalUSDC runtime_common::migrations::local_currency::register::Migration< super::Runtime, diff --git a/runtime/development/src/xcm.rs b/runtime/development/src/xcm.rs index 64045a922d..1e8313b57f 100644 --- a/runtime/development/src/xcm.rs +++ b/runtime/development/src/xcm.rs @@ -28,7 +28,7 @@ use runtime_common::{ transfer_filter::PreXcmTransfer, xcm::{ general_key, AccountIdToMultiLocation, Barrier, FixedConversionRateProvider, - LpInstanceRelayer, ToTreasury, + LocalOriginToLocation, LpInstanceRelayer, ToTreasury, }, xcm_fees::native_per_second, }; @@ -37,7 +37,7 @@ use xcm::{latest::Weight as XcmWeight, prelude::*, v3::MultiLocation}; use xcm_builder::{ ConvertedConcreteId, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, NoChecking, RelayChainAsNative, SiblingParachainAsNative, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, + SovereignSignedViaLocation, }; use xcm_executor::{traits::JustTry, XcmExecutor}; @@ -169,7 +169,7 @@ impl pallet_xcm::Config for Runtime { type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; type Currency = crate::Balances; type CurrencyMatcher = (); - type ExecuteXcmOrigin = EnsureXcmOrigin; + type ExecuteXcmOrigin = EnsureXcmOrigin>; type MaxLockers = ConstU32<8>; type MaxRemoteLockConsumers = ConstU32<0>; #[cfg(feature = "runtime-benchmarks")] @@ -178,7 +178,7 @@ impl pallet_xcm::Config for Runtime { type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; - type SendXcmOrigin = EnsureXcmOrigin; + type SendXcmOrigin = EnsureXcmOrigin>; type SovereignAccountOf = LocationToAccountId; type TrustedLockers = (); type UniversalLocation = UniversalLocation; @@ -203,9 +203,6 @@ parameter_types! { pub type CurrencyIdConvert = runtime_common::xcm::CurrencyIdConvert; pub type LocationToAccountId = runtime_common::xcm::LocationToAccountId; -/// No local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = SignedToAccountId32; - /// The means for routing XCM messages which are not for local execution /// into the right message queues. pub type XcmRouter = ( diff --git a/runtime/integration-tests/src/generic/cases/account_derivation.rs b/runtime/integration-tests/src/generic/cases/account_derivation.rs new file mode 100644 index 0000000000..378c13f209 --- /dev/null +++ b/runtime/integration-tests/src/generic/cases/account_derivation.rs @@ -0,0 +1,240 @@ +// Copyright 2021 Centrifuge Foundation (centrifuge.io). +// +// This file is part of the Centrifuge chain project. +// Centrifuge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version (see http://www.gnu.org/licenses). +// Centrifuge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +//! Testing essential account derivations that are done in the runtime + +use cfg_primitives::AccountId; +use runtime_common::apis::runtime_decl_for_account_conversion_api::AccountConversionApi; +use sp_runtime::traits::{Get, Zero}; +use xcm::v3::{ + Junction::{AccountId32, AccountKey20, Parachain}, + Junctions::{X1, X2}, + MultiLocation, NetworkId, +}; + +use crate::generic::{config::Runtime, env::Env, envs::runtime_env::RuntimeEnv}; + +const KEY_20: [u8; 20] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +]; + +const KEY_32: [u8; 32] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, +]; + +const RANDOM_EVM_ID: u64 = 7868687u64; + +const RANDOM_PARA_ID: u32 = 1230412u32; + +fn network_id(chain_id: u64) -> Option { + Some(NetworkId::Ethereum { chain_id }) +} + +fn evm_derivation_copy(chain_id: u64) -> AccountId { + let tag = b"EVM"; + let mut bytes = [0; 32]; + bytes[0..20].copy_from_slice(&KEY_20); + bytes[20..28].copy_from_slice(&chain_id.to_be_bytes()); + bytes[28..31].copy_from_slice(tag); + AccountId::new(bytes) +} + +fn local_evm_account() { + let env = RuntimeEnv::::default(); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 0, + X1(AccountKey20 { + key: KEY_20, + network: network_id(pallet_evm_chain_id::Pallet::::get()), + }), + )) + .unwrap() + }); + + assert_eq!( + evm_derivation_copy(env.parachain_state(pallet_evm_chain_id::Pallet::::get)), + derived + ); +} + +fn lp_evm_account() { + let env = RuntimeEnv::::default(); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 0, + X1(AccountKey20 { + key: KEY_20, + network: network_id(RANDOM_EVM_ID), + }), + )) + .unwrap() + }); + + assert_eq!(evm_derivation_copy(RANDOM_EVM_ID), derived); +} + +fn relay_chain_account() { + let env = RuntimeEnv::::default(); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 1, + X1(AccountKey20 { + key: KEY_20, + network: None, + }), + )) + .unwrap() + }); + + assert_eq!( + AccountId::new([ + 4, 59, 209, 254, 99, 95, 243, 33, 66, 81, 61, 173, 89, 50, 167, 168, 127, 205, 21, 181, + 140, 236, 38, 204, 219, 245, 163, 125, 94, 12, 60, 229 + ]), + derived + ); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 1, + X1(AccountId32 { + id: KEY_32, + network: None, + }), + )) + .unwrap() + }); + + assert_eq!( + AccountId::new([ + 254, 215, 56, 52, 116, 98, 213, 210, 66, 203, 84, 103, 189, 233, 54, 117, 31, 174, 247, + 234, 64, 173, 211, 235, 181, 10, 68, 230, 98, 50, 132, 44 + ]), + derived + ); +} + +fn sibling_chain_account() { + let env = RuntimeEnv::::default(); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 1, + X2( + Parachain(RANDOM_PARA_ID), + AccountKey20 { + key: KEY_20, + network: None, + }, + ), + )) + .unwrap() + }); + + assert_eq!( + AccountId::new([ + 201, 87, 44, 251, 77, 114, 74, 143, 48, 100, 31, 110, 2, 1, 181, 223, 57, 225, 98, 105, + 223, 208, 198, 185, 81, 33, 105, 208, 64, 93, 239, 106 + ]), + derived + ); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 1, + X2( + Parachain(RANDOM_PARA_ID), + AccountId32 { + id: KEY_32, + network: None, + }, + ), + )) + .unwrap() + }); + + assert_eq!( + AccountId::new([ + 232, 18, 32, 29, 7, 230, 102, 47, 36, 250, 204, 9, 156, 40, 170, 26, 102, 176, 9, 149, + 41, 14, 24, 80, 7, 167, 190, 125, 109, 218, 84, 152 + ]), + derived + ); +} + +fn remote_account_on_relay() { + let env = RuntimeEnv::::default(); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 0, + X2( + Parachain(parachain_info::Pallet::::get().into()), + AccountId32 { + id: KEY_32, + network: Some(NetworkId::ByGenesis( + frame_system::BlockHash::::get(T::BlockNumber::zero()).0, + )), + }, + ), + )) + .unwrap() + }); + + assert_eq!( + AccountId::new([ + 158, 225, 206, 240, 254, 14, 246, 36, 122, 8, 206, 79, 16, 214, 249, 210, 196, 152, + 224, 228, 248, 52, 181, 154, 219, 40, 14, 225, 32, 91, 187, 233 + ]), + derived + ); +} + +fn remote_account_on_sibling() { + let env = RuntimeEnv::::default(); + + let derived = env.parachain_state(|| { + T::Api::conversion_of(MultiLocation::new( + 1, + X2( + Parachain(parachain_info::Pallet::::get().into()), + AccountId32 { + id: KEY_32, + network: Some(NetworkId::ByGenesis( + frame_system::BlockHash::::get(T::BlockNumber::zero()).0, + )), + }, + ), + )) + .unwrap() + }); + + assert_eq!( + AccountId::new([ + 126, 34, 185, 2, 219, 222, 98, 177, 214, 201, 96, 61, 209, 76, 224, 101, 48, 109, 75, + 24, 52, 172, 163, 5, 23, 233, 74, 249, 105, 114, 211, 143 + ]), + derived + ); +} + +crate::test_for_runtimes!(all, local_evm_account); +crate::test_for_runtimes!(all, lp_evm_account); +crate::test_for_runtimes!(all, relay_chain_account); +crate::test_for_runtimes!(all, sibling_chain_account); +crate::test_for_runtimes!(all, remote_account_on_relay); +crate::test_for_runtimes!(all, remote_account_on_sibling); diff --git a/runtime/integration-tests/src/generic/config.rs b/runtime/integration-tests/src/generic/config.rs index a63ffec5ce..07e977baf3 100644 --- a/runtime/integration-tests/src/generic/config.rs +++ b/runtime/integration-tests/src/generic/config.rs @@ -265,6 +265,9 @@ pub trait Runtime: AccountId, TrancheCurrency, InvestmentPortfolio, + > + apis::runtime_decl_for_account_conversion_api::AccountConversionApiV1< + Self::Block, + AccountId, >; type MaxTranchesExt: Codec + Get + Member + PartialOrd + TypeInfo; diff --git a/runtime/integration-tests/src/generic/envs/runtime_env.rs b/runtime/integration-tests/src/generic/envs/runtime_env.rs index 44ae466432..036d8c2230 100644 --- a/runtime/integration-tests/src/generic/envs/runtime_env.rs +++ b/runtime/integration-tests/src/generic/envs/runtime_env.rs @@ -93,7 +93,7 @@ impl Env for RuntimeEnv { call: impl Into, ) -> Result { let call: T::RuntimeCallExt = call.into(); - let info = call.get_dispatch_info(); + let info = self.parachain_state(|| call.get_dispatch_info()); let extrinsic = self.parachain_state(|| { let nonce = frame_system::Pallet::::account(who.to_account_id()).nonce; diff --git a/runtime/integration-tests/src/generic/mod.rs b/runtime/integration-tests/src/generic/mod.rs index 118c7a26bf..5e21be5bc1 100644 --- a/runtime/integration-tests/src/generic/mod.rs +++ b/runtime/integration-tests/src/generic/mod.rs @@ -14,6 +14,7 @@ pub mod utils; // Test cases mod cases { + mod account_derivation; mod example; mod investments; mod liquidity_pools;