Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update and abstract common xcm configs #2600

Merged
merged 2 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion runtime/acala/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1560,7 +1560,7 @@ impl module_xcm_interface::Config for Runtime {
type RelayChainCallBuilder = RelayChainCallBuilder<ParachainInfo>;
type XcmTransfer = XTokens;
type SelfLocation = xcm_config::SelfLocation;
type AccountIdToMultiLocation = xcm_config::AccountIdToMultiLocation;
type AccountIdToMultiLocation = runtime_common::xcm_config::AccountIdToMultiLocation;
}

impl orml_unknown_tokens::Config for Runtime {
Expand Down
101 changes: 16 additions & 85 deletions runtime/acala/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,103 +24,45 @@ use super::{
XcmInterface, XcmpQueue, ACA, AUSD, TAP,
};
use codec::{Decode, Encode};
pub use cumulus_primitives_core::ParaId;
pub use frame_support::{
use frame_support::{
parameter_types,
traits::{ConstU32, Everything, Get, Nothing},
weights::Weight,
};
use module_asset_registry::{
BuyWeightRateOfErc20, BuyWeightRateOfForeignAsset, BuyWeightRateOfLiquidCrowdloan, BuyWeightRateOfStableAsset,
};
use module_support::HomaSubAccountXcm;
use module_transaction_payment::BuyWeightRateOfTransactionFeePool;
use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key, MultiCurrency};
use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};
use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset};
use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use primitives::evm::is_system_contract;
use runtime_common::{
local_currency_location, native_currency_location, xcm_impl::AccountKey20Aliases, AcalaDropAssets,
EnsureRootOrHalfGeneralCouncil, EnsureRootOrThreeFourthsGeneralCouncil, FixedRateOfAsset,
local_currency_location, native_currency_location, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil,
EnsureRootOrThreeFourthsGeneralCouncil, FixedRateOfAsset,
};
use xcm::{prelude::*, v3::Weight as XcmWeight};
pub use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
AllowUnpaidExecutionFrom, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, NativeAsset,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit,
};
use xcm_builder::{EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, SignedToAccountId32};

parameter_types! {
pub DotLocation: MultiLocation = MultiLocation::parent();
pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into()));
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
}

/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
/// `Transact` in order to determine the dispatch RuntimeOrigin.
pub type LocationToAccountId = (
// The parent (Relay-chain) origin converts to the default `AccountId`.
ParentIsPreset<AccountId>,
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
// Convert `AccountKey20` to `AccountId`
AccountKey20Aliases<RelayNetwork, AccountId, EvmAddressMapping<Runtime>>,
);
pub type LocationToAccountId =
runtime_common::xcm_config::LocationToAccountId<RelayNetwork, EvmAddressMapping<Runtime>>;

/// This is the type we use to convert an (incoming) XCM origin into a local `RuntimeOrigin`
/// instance, ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind`
/// which can biases the kind of local `RuntimeOrigin` it will become.
pub type XcmOriginToCallOrigin = (
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
// foreign chains who want to have a local sovereign account on this chain which they control.
SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
// recognized.
RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
// recognized.
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
// Native signed account converter; this just converts an `AccountId32` origin into a normal
// `RuntimeOrigin::Signed` origin of the same 32-byte value.
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
XcmPassthrough<RuntimeOrigin>,
);
pub type XcmOriginToCallOrigin = runtime_common::xcm_config::XcmOriginToCallOrigin<
LocationToAccountId,
RuntimeOrigin,
RelayChainOrigin,
RelayNetwork,
>;

pub type Barrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
// Expected responses are OK.
AllowKnownQueryResponses<PolkadotXcm>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<Everything>,
);
pub type Barrier = runtime_common::xcm_config::Barrier<PolkadotXcm, UniversalLocation>;

pub struct ToTreasury;
impl TakeRevenue for ToTreasury {
fn take_revenue(revenue: MultiAsset) {
if let MultiAsset {
id: Concrete(location),
fun: Fungible(amount),
} = revenue
{
if let Some(currency_id) = CurrencyIdConvert::convert(location) {
// Ensure AcalaTreasuryAccount have ed requirement for native asset, but don't need
// ed requirement for cross-chain asset because it's one of whitelist accounts.
// Ignore the result.
let _ = Currencies::deposit(currency_id, &AcalaTreasuryAccount::get(), amount);
}
}
}
}
pub type ToTreasury = runtime_common::xcm_config::ToTreasury<CurrencyIdConvert, AcalaTreasuryAccount, Currencies>;

parameter_types! {
// One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer.
Expand Down Expand Up @@ -377,17 +319,6 @@ parameter_types! {
pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));
}

pub struct AccountIdToMultiLocation;
impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {
fn convert(account: AccountId) -> MultiLocation {
X1(AccountId32 {
network: None,
id: account.into(),
})
.into()
}
}

parameter_types! {
pub const BaseXcmWeight: XcmWeight = XcmWeight::from_parts(100_000_000, 0);
pub const MaxAssetsForTransfer: usize = 2;
Expand All @@ -408,7 +339,7 @@ impl orml_xtokens::Config for Runtime {
type Balance = Balance;
type CurrencyId = CurrencyId;
type CurrencyIdConvert = CurrencyIdConvert;
type AccountIdToMultiLocation = AccountIdToMultiLocation;
type AccountIdToMultiLocation = runtime_common::xcm_config::AccountIdToMultiLocation;
type SelfLocation = SelfLocation;
type XcmExecutor = XcmExecutor;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
Expand Down
3 changes: 2 additions & 1 deletion runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v1

# cumulus
cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v1.0.0", default-features = false }
cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v1.0.0", default-features = false }

# polkadot
pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v1.0.0", default-features = false, optional = true }
pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v1.0.0", default-features = false }
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v1.0.0", default-features = false }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v1.0.0", default-features = false }
xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v1.0.0", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ use std::{collections::btree_map::BTreeMap, str::FromStr};
pub mod bench;
pub mod check_nonce;
pub mod precompile;
pub mod xcm_config;
pub mod xcm_impl;

mod gas_to_weight_ratio;
Expand Down
130 changes: 130 additions & 0 deletions runtime/common/src/xcm_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// This file is part of Acala.

// Copyright (C) 2020-2023 Acala Foundation.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{xcm_impl::AccountKey20Aliases, AccountId, Balance, Convert, CurrencyId};
use frame_support::{
match_types,
traits::{ConstU32, Everything, Get},
};
use orml_traits::MultiCurrency;
use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, TrailingSetTopicAsId,
WithComputedOrigin,
};

/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
/// `Transact` in order to determine the dispatch RuntimeOrigin.
pub type LocationToAccountId<RelayNetwork, EvmAddressMapping> = (
// The parent (Relay-chain) origin converts to the default `AccountId`.
ParentIsPreset<AccountId>,
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
SiblingParachainConvertsVia<Sibling, AccountId>,
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
// Convert `AccountKey20` to `AccountId`
AccountKey20Aliases<RelayNetwork, AccountId, EvmAddressMapping>,
);

/// This is the type we use to convert an (incoming) XCM origin into a local `RuntimeOrigin`
/// instance, ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind`
/// which can biases the kind of local `RuntimeOrigin` it will become.
pub type XcmOriginToCallOrigin<LocationToAccountId, RuntimeOrigin, RelayChainOrigin, RelayNetwork> = (
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
// foreign chains who want to have a local sovereign account on this chain which they control.
SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
// recognized.
RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
// recognized.
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
// Native signed account converter; this just converts an `AccountId32` origin into a normal
// `RuntimeOrigin::Signed` origin of the same 32-byte value.
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
XcmPassthrough<RuntimeOrigin>,
);

match_types! {
pub type ParentOrSiblings: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: Here } |
MultiLocation { parents: 1, interior: X1(_) }
};
}

pub type Barrier<PolkadotXcm, UniversalLocation> = TrailingSetTopicAsId<(
TakeWeightCredit,
// Expected responses are OK.
AllowKnownQueryResponses<PolkadotXcm>,
// Allow XCMs with some computed origins to pass through.
WithComputedOrigin<
(
// If the message is one that immediately attemps to pay for execution, then
// allow it.
AllowTopLevelPaidExecutionFrom<Everything>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<ParentOrSiblings>,
),
UniversalLocation,
ConstU32<8>,
>,
)>;

pub struct ToTreasury<CurrencyIdConvert, AcalaTreasuryAccount, Currencies>(
sp_std::marker::PhantomData<(CurrencyIdConvert, AcalaTreasuryAccount, Currencies)>,
);
impl<CurrencyIdConvert, AcalaTreasuryAccount, Currencies> TakeRevenue
for ToTreasury<CurrencyIdConvert, AcalaTreasuryAccount, Currencies>
where
AcalaTreasuryAccount: Get<AccountId>,
CurrencyIdConvert: Convert<MultiLocation, Option<CurrencyId>>,
Currencies: MultiCurrency<AccountId, CurrencyId = CurrencyId, Balance = Balance>,
{
fn take_revenue(revenue: MultiAsset) {
if let MultiAsset {
id: Concrete(location),
fun: Fungible(amount),
} = revenue
{
if let Some(currency_id) = CurrencyIdConvert::convert(location) {
// Ensure AcalaTreasuryAccount have ed requirement for native asset, but don't need
// ed requirement for cross-chain asset because it's one of whitelist accounts.
// Ignore the result.
let _ = Currencies::deposit(currency_id, &AcalaTreasuryAccount::get(), amount);
}
}
}
}

pub struct AccountIdToMultiLocation;
impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {
fn convert(account: AccountId) -> MultiLocation {
X1(AccountId32 {
network: None,
id: account.into(),
})
.into()
}
}
2 changes: 1 addition & 1 deletion runtime/karura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ impl module_xcm_interface::Config for Runtime {
type RelayChainCallBuilder = RelayChainCallBuilder<ParachainInfo>;
type XcmTransfer = XTokens;
type SelfLocation = xcm_config::SelfLocation;
type AccountIdToMultiLocation = xcm_config::AccountIdToMultiLocation;
type AccountIdToMultiLocation = runtime_common::xcm_config::AccountIdToMultiLocation;
}

impl orml_unknown_tokens::Config for Runtime {
Expand Down
Loading