mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
cargo +nightly fmt (#3540)
* cargo +nightly fmt * add cargo-fmt check to ci * update ci * fmt * fmt * skip macro * ignore bridges
This commit is contained in:
@@ -16,11 +16,11 @@
|
||||
|
||||
//! Various implementations for `ShouldExecute`.
|
||||
|
||||
use sp_std::{result::Result, marker::PhantomData};
|
||||
use xcm::v0::{Xcm, Order, MultiLocation, Junction};
|
||||
use frame_support::{ensure, traits::Contains, weights::Weight};
|
||||
use xcm_executor::traits::{OnResponse, ShouldExecute};
|
||||
use polkadot_parachain::primitives::IsSystem;
|
||||
use sp_std::{marker::PhantomData, result::Result};
|
||||
use xcm::v0::{Junction, MultiLocation, Order, Xcm};
|
||||
use xcm_executor::traits::{OnResponse, ShouldExecute};
|
||||
|
||||
/// Execution barrier that just takes `shallow_weight` from `weight_credit`.
|
||||
pub struct TakeWeightCredit;
|
||||
@@ -51,14 +51,14 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFro
|
||||
ensure!(T::contains(origin), ());
|
||||
ensure!(top_level, ());
|
||||
match message {
|
||||
Xcm::TeleportAsset { effects, .. }
|
||||
| Xcm::WithdrawAsset { effects, ..}
|
||||
| Xcm::ReserveAssetDeposit { effects, ..}
|
||||
if matches!(
|
||||
Xcm::TeleportAsset { effects, .. } |
|
||||
Xcm::WithdrawAsset { effects, .. } |
|
||||
Xcm::ReserveAssetDeposit { effects, .. }
|
||||
if matches!(
|
||||
effects.first(),
|
||||
Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight
|
||||
)
|
||||
=> Ok(()),
|
||||
) =>
|
||||
Ok(()),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@@ -82,9 +82,7 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowUnpaidExecutionFrom<T> {
|
||||
|
||||
/// Allows a message only if it is from a system-level child parachain.
|
||||
pub struct IsChildSystemParachain<ParaId>(PhantomData<ParaId>);
|
||||
impl<
|
||||
ParaId: IsSystem + From<u32>,
|
||||
> Contains<MultiLocation> for IsChildSystemParachain<ParaId> {
|
||||
impl<ParaId: IsSystem + From<u32>> Contains<MultiLocation> for IsChildSystemParachain<ParaId> {
|
||||
fn contains(l: &MultiLocation) -> bool {
|
||||
matches!(l, MultiLocation::X1(Junction::Parachain(id)) if ParaId::from(*id).is_system())
|
||||
}
|
||||
@@ -101,8 +99,9 @@ impl<ResponseHandler: OnResponse> ShouldExecute for AllowKnownQueryResponses<Res
|
||||
_weight_credit: &mut Weight,
|
||||
) -> Result<(), ()> {
|
||||
match message {
|
||||
Xcm::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id)
|
||||
=> Ok(()),
|
||||
Xcm::QueryResponse { query_id, .. }
|
||||
if ResponseHandler::expecting_response(origin, *query_id) =>
|
||||
Ok(()),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
//! Adapters to work with `frame_support::traits::Currency` through XCM.
|
||||
|
||||
use sp_std::{result, convert::TryInto, marker::PhantomData};
|
||||
use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation};
|
||||
use sp_runtime::traits::{SaturatedConversion, CheckedSub};
|
||||
use frame_support::traits::{ExistenceRequirement::AllowDeath, WithdrawReasons, Get};
|
||||
use xcm_executor::traits::{MatchesFungible, Convert, TransactAsset};
|
||||
use xcm_executor::Assets;
|
||||
use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons};
|
||||
use sp_runtime::traits::{CheckedSub, SaturatedConversion};
|
||||
use sp_std::{convert::TryInto, marker::PhantomData, result};
|
||||
use xcm::v0::{Error as XcmError, MultiAsset, MultiLocation, Result};
|
||||
use xcm_executor::{
|
||||
traits::{Convert, MatchesFungible, TransactAsset},
|
||||
Assets,
|
||||
};
|
||||
|
||||
/// Asset transaction errors.
|
||||
enum Error {
|
||||
@@ -39,7 +41,8 @@ impl From<Error> for XcmError {
|
||||
match e {
|
||||
Error::AssetNotFound => XcmError::AssetNotFound,
|
||||
Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"),
|
||||
Error::AmountToBalanceConversionFailed => FailedToTransactAsset("AmountToBalanceConversionFailed"),
|
||||
Error::AmountToBalanceConversionFailed =>
|
||||
FailedToTransactAsset("AmountToBalanceConversionFailed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,26 +84,33 @@ impl From<Error> for XcmError {
|
||||
/// >;
|
||||
/// ```
|
||||
pub struct CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount>(
|
||||
PhantomData<(Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount)>
|
||||
PhantomData<(Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount)>,
|
||||
);
|
||||
|
||||
impl<
|
||||
Matcher: MatchesFungible<Currency::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
Currency: frame_support::traits::Currency<AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
CheckedAccount: Get<Option<AccountId>>,
|
||||
> TransactAsset for CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount> {
|
||||
Matcher: MatchesFungible<Currency::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
Currency: frame_support::traits::Currency<AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
CheckedAccount: Get<Option<AccountId>>,
|
||||
> TransactAsset
|
||||
for CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount>
|
||||
{
|
||||
fn can_check_in(_origin: &MultiLocation, what: &MultiAsset) -> Result {
|
||||
// Check we handle this asset.
|
||||
let amount: Currency::Balance = Matcher::matches_fungible(what)
|
||||
.ok_or(Error::AssetNotFound)?;
|
||||
let amount: Currency::Balance =
|
||||
Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?;
|
||||
if let Some(checked_account) = CheckedAccount::get() {
|
||||
let new_balance = Currency::free_balance(&checked_account)
|
||||
.checked_sub(&amount)
|
||||
.ok_or(XcmError::NotWithdrawable)?;
|
||||
Currency::ensure_can_withdraw(&checked_account, amount, WithdrawReasons::TRANSFER, new_balance)
|
||||
.map_err(|_| XcmError::NotWithdrawable)?;
|
||||
Currency::ensure_can_withdraw(
|
||||
&checked_account,
|
||||
amount,
|
||||
WithdrawReasons::TRANSFER,
|
||||
new_balance,
|
||||
)
|
||||
.map_err(|_| XcmError::NotWithdrawable)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -108,8 +118,17 @@ impl<
|
||||
fn check_in(_origin: &MultiLocation, what: &MultiAsset) {
|
||||
if let Some(amount) = Matcher::matches_fungible(what) {
|
||||
if let Some(checked_account) = CheckedAccount::get() {
|
||||
let ok = Currency::withdraw(&checked_account, amount, WithdrawReasons::TRANSFER, AllowDeath).is_ok();
|
||||
debug_assert!(ok, "`can_check_in` must have returned `true` immediately prior; qed");
|
||||
let ok = Currency::withdraw(
|
||||
&checked_account,
|
||||
amount,
|
||||
WithdrawReasons::TRANSFER,
|
||||
AllowDeath,
|
||||
)
|
||||
.is_ok();
|
||||
debug_assert!(
|
||||
ok,
|
||||
"`can_check_in` must have returned `true` immediately prior; qed"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,31 +143,24 @@ impl<
|
||||
|
||||
fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result {
|
||||
// Check we handle this asset.
|
||||
let amount: u128 = Matcher::matches_fungible(&what)
|
||||
.ok_or(Error::AssetNotFound)?
|
||||
.saturated_into();
|
||||
let who = AccountIdConverter::convert_ref(who)
|
||||
.map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
let balance_amount = amount
|
||||
.try_into()
|
||||
.map_err(|_| Error::AmountToBalanceConversionFailed)?;
|
||||
let amount: u128 =
|
||||
Matcher::matches_fungible(&what).ok_or(Error::AssetNotFound)?.saturated_into();
|
||||
let who =
|
||||
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
let balance_amount =
|
||||
amount.try_into().map_err(|_| Error::AmountToBalanceConversionFailed)?;
|
||||
let _imbalance = Currency::deposit_creating(&who, balance_amount);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn withdraw_asset(
|
||||
what: &MultiAsset,
|
||||
who: &MultiLocation
|
||||
) -> result::Result<Assets, XcmError> {
|
||||
fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> result::Result<Assets, XcmError> {
|
||||
// Check we handle this asset.
|
||||
let amount: u128 = Matcher::matches_fungible(what)
|
||||
.ok_or(Error::AssetNotFound)?
|
||||
.saturated_into();
|
||||
let who = AccountIdConverter::convert_ref(who)
|
||||
.map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
let balance_amount = amount
|
||||
.try_into()
|
||||
.map_err(|_| Error::AmountToBalanceConversionFailed)?;
|
||||
let amount: u128 =
|
||||
Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?.saturated_into();
|
||||
let who =
|
||||
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
let balance_amount =
|
||||
amount.try_into().map_err(|_| Error::AmountToBalanceConversionFailed)?;
|
||||
Currency::withdraw(&who, balance_amount, WithdrawReasons::TRANSFER, AllowDeath)
|
||||
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
|
||||
Ok(what.clone().into())
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
//! Various implementations of `FilterAssetLocation`.
|
||||
|
||||
use frame_support::traits::Get;
|
||||
use sp_std::marker::PhantomData;
|
||||
use xcm::v0::{MultiAsset, MultiLocation};
|
||||
use frame_support::traits::Get;
|
||||
use xcm_executor::traits::FilterAssetLocation;
|
||||
|
||||
/// Accepts an asset iff it is a native asset.
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
|
||||
//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
|
||||
|
||||
use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow};
|
||||
use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction};
|
||||
use frame_support::traits::{Get, tokens::fungibles, Contains};
|
||||
use xcm_executor::traits::{TransactAsset, Convert, MatchesFungibles, Error as MatchError};
|
||||
use frame_support::traits::{tokens::fungibles, Contains, Get};
|
||||
use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
|
||||
use xcm::v0::{Error as XcmError, Junction, MultiAsset, MultiLocation, Result};
|
||||
use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, TransactAsset};
|
||||
|
||||
/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be `TryFrom/TryInto<u128>`) into
|
||||
/// a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will typically be a
|
||||
/// `PalletInstance` junction.
|
||||
pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(PhantomData<(Prefix, AssetId, ConvertAssetId)>);
|
||||
impl<
|
||||
Prefix: Get<MultiLocation>,
|
||||
AssetId: Clone,
|
||||
ConvertAssetId: Convert<u128, AssetId>,
|
||||
> Convert<MultiLocation, AssetId> for AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId> {
|
||||
pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(
|
||||
PhantomData<(Prefix, AssetId, ConvertAssetId)>,
|
||||
);
|
||||
impl<Prefix: Get<MultiLocation>, AssetId: Clone, ConvertAssetId: Convert<u128, AssetId>>
|
||||
Convert<MultiLocation, AssetId> for AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>
|
||||
{
|
||||
fn convert_ref(id: impl Borrow<MultiLocation>) -> result::Result<AssetId, ()> {
|
||||
let prefix = Prefix::get();
|
||||
let id = id.borrow();
|
||||
@@ -50,58 +50,63 @@ impl<
|
||||
}
|
||||
|
||||
pub struct ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
|
||||
PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>
|
||||
PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>,
|
||||
);
|
||||
impl<
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
ConvertAssetId: Convert<MultiLocation, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
> MatchesFungibles<AssetId, Balance> for
|
||||
ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
ConvertAssetId: Convert<MultiLocation, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
> MatchesFungibles<AssetId, Balance>
|
||||
for ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
{
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||
let (id, amount) = match a {
|
||||
MultiAsset::ConcreteFungible { id, amount } => (id, amount),
|
||||
_ => return Err(MatchError::AssetNotFound),
|
||||
};
|
||||
let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||
let what =
|
||||
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount)
|
||||
.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||
Ok((what, amount))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
|
||||
PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>
|
||||
PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>,
|
||||
);
|
||||
impl<
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
ConvertAssetId: Convert<Vec<u8>, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
> MatchesFungibles<AssetId, Balance> for
|
||||
ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
ConvertAssetId: Convert<Vec<u8>, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
> MatchesFungibles<AssetId, Balance>
|
||||
for ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
{
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||
let (id, amount) = match a {
|
||||
MultiAsset::AbstractFungible { id, amount } => (id, amount),
|
||||
_ => return Err(MatchError::AssetNotFound),
|
||||
};
|
||||
let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||
let what =
|
||||
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount)
|
||||
.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||
Ok((what, amount))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>(
|
||||
PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>
|
||||
PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>,
|
||||
);
|
||||
impl<
|
||||
Assets: fungibles::Transfer<AccountId>,
|
||||
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
> TransactAsset for FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId> {
|
||||
Assets: fungibles::Transfer<AccountId>,
|
||||
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
> TransactAsset for FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>
|
||||
{
|
||||
fn transfer_asset(
|
||||
what: &MultiAsset,
|
||||
from: &MultiLocation,
|
||||
@@ -119,17 +124,31 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FungiblesMutateAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>(
|
||||
PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>
|
||||
);
|
||||
pub struct FungiblesMutateAdapter<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>);
|
||||
impl<
|
||||
Assets: fungibles::Mutate<AccountId>,
|
||||
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
CheckAsset: Contains<Assets::AssetId>,
|
||||
CheckingAccount: Get<AccountId>,
|
||||
> TransactAsset for FungiblesMutateAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount> {
|
||||
Assets: fungibles::Mutate<AccountId>,
|
||||
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
CheckAsset: Contains<Assets::AssetId>,
|
||||
CheckingAccount: Get<AccountId>,
|
||||
> TransactAsset
|
||||
for FungiblesMutateAdapter<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>
|
||||
{
|
||||
fn can_check_in(_origin: &MultiLocation, what: &MultiAsset) -> Result {
|
||||
// Check we handle this asset.
|
||||
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
|
||||
@@ -148,7 +167,10 @@ impl<
|
||||
if CheckAsset::contains(&asset_id) {
|
||||
let checking_account = CheckingAccount::get();
|
||||
let ok = Assets::burn_from(asset_id, &checking_account, amount).is_ok();
|
||||
debug_assert!(ok, "`can_check_in` must have returned `true` immediately prior; qed");
|
||||
debug_assert!(
|
||||
ok,
|
||||
"`can_check_in` must have returned `true` immediately prior; qed"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,7 +196,7 @@ impl<
|
||||
|
||||
fn withdraw_asset(
|
||||
what: &MultiAsset,
|
||||
who: &MultiLocation
|
||||
who: &MultiLocation,
|
||||
) -> result::Result<xcm_executor::Assets, XcmError> {
|
||||
// Check we handle this asset.
|
||||
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
|
||||
@@ -186,43 +208,80 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FungiblesAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>(
|
||||
PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>
|
||||
);
|
||||
pub struct FungiblesAdapter<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>);
|
||||
impl<
|
||||
Assets: fungibles::Mutate<AccountId> + fungibles::Transfer<AccountId>,
|
||||
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
CheckAsset: Contains<Assets::AssetId>,
|
||||
CheckingAccount: Get<AccountId>,
|
||||
> TransactAsset for FungiblesAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount> {
|
||||
Assets: fungibles::Mutate<AccountId> + fungibles::Transfer<AccountId>,
|
||||
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
|
||||
AccountIdConverter: Convert<MultiLocation, AccountId>,
|
||||
AccountId: Clone, // can't get away without it since Currency is generic over it.
|
||||
CheckAsset: Contains<Assets::AssetId>,
|
||||
CheckingAccount: Get<AccountId>,
|
||||
> TransactAsset
|
||||
for FungiblesAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
|
||||
{
|
||||
fn can_check_in(origin: &MultiLocation, what: &MultiAsset) -> Result {
|
||||
FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
|
||||
::can_check_in(origin, what)
|
||||
FungiblesMutateAdapter::<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>::can_check_in(origin, what)
|
||||
}
|
||||
|
||||
fn check_in(origin: &MultiLocation, what: &MultiAsset) {
|
||||
FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
|
||||
::check_in(origin, what)
|
||||
FungiblesMutateAdapter::<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>::check_in(origin, what)
|
||||
}
|
||||
|
||||
fn check_out(dest: &MultiLocation, what: &MultiAsset) {
|
||||
FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
|
||||
::check_out(dest, what)
|
||||
FungiblesMutateAdapter::<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>::check_out(dest, what)
|
||||
}
|
||||
|
||||
fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result {
|
||||
FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
|
||||
::deposit_asset(what, who)
|
||||
FungiblesMutateAdapter::<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>::deposit_asset(what, who)
|
||||
}
|
||||
|
||||
fn withdraw_asset(
|
||||
what: &MultiAsset,
|
||||
who: &MultiLocation
|
||||
who: &MultiLocation,
|
||||
) -> result::Result<xcm_executor::Assets, XcmError> {
|
||||
FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
|
||||
::withdraw_asset(what, who)
|
||||
FungiblesMutateAdapter::<
|
||||
Assets,
|
||||
Matcher,
|
||||
AccountIdConverter,
|
||||
AccountId,
|
||||
CheckAsset,
|
||||
CheckingAccount,
|
||||
>::withdraw_asset(what, who)
|
||||
}
|
||||
|
||||
fn transfer_asset(
|
||||
@@ -230,6 +289,8 @@ impl<
|
||||
from: &MultiLocation,
|
||||
to: &MultiLocation,
|
||||
) -> result::Result<xcm_executor::Assets, XcmError> {
|
||||
FungiblesTransferAdapter::<Assets, Matcher, AccountIdConverter, AccountId>::transfer_asset(what, from, to)
|
||||
FungiblesTransferAdapter::<Assets, Matcher, AccountIdConverter, AccountId>::transfer_asset(
|
||||
what, from, to,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,21 +27,22 @@ mod tests;
|
||||
|
||||
mod location_conversion;
|
||||
pub use location_conversion::{
|
||||
Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases,
|
||||
AccountKey20Aliases, LocationInverter,
|
||||
Account32Hash, AccountId32Aliases, AccountKey20Aliases, ChildParachainConvertsVia,
|
||||
LocationInverter, ParentIsDefault, SiblingParachainConvertsVia,
|
||||
};
|
||||
|
||||
mod origin_conversion;
|
||||
pub use origin_conversion::{
|
||||
SovereignSignedViaLocation, ParentAsSuperuser, ChildSystemParachainAsSuperuser, SiblingSystemParachainAsSuperuser,
|
||||
ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative,
|
||||
SignedAccountKey20AsNative, EnsureXcmOrigin, SignedToAccountId32, BackingToPlurality,
|
||||
BackingToPlurality, ChildParachainAsNative, ChildSystemParachainAsSuperuser, EnsureXcmOrigin,
|
||||
ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative,
|
||||
SiblingSystemParachainAsSuperuser, SignedAccountId32AsNative, SignedAccountKey20AsNative,
|
||||
SignedToAccountId32, SovereignSignedViaLocation,
|
||||
};
|
||||
|
||||
mod barriers;
|
||||
pub use barriers::{
|
||||
TakeWeightCredit, AllowUnpaidExecutionFrom, AllowTopLevelPaidExecutionFrom, AllowKnownQueryResponses,
|
||||
IsChildSystemParachain,
|
||||
AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
|
||||
IsChildSystemParachain, TakeWeightCredit,
|
||||
};
|
||||
|
||||
mod currency_adapter;
|
||||
@@ -50,11 +51,11 @@ pub use currency_adapter::CurrencyAdapter;
|
||||
mod fungibles_adapter;
|
||||
pub use fungibles_adapter::{
|
||||
AsPrefixedGeneralIndex, ConvertedAbstractAssetId, ConvertedConcreteAssetId, FungiblesAdapter,
|
||||
FungiblesMutateAdapter, FungiblesTransferAdapter
|
||||
FungiblesMutateAdapter, FungiblesTransferAdapter,
|
||||
};
|
||||
|
||||
mod weight;
|
||||
pub use weight::{FixedRateOfConcreteFungible, FixedWeightBounds, UsingComponents, TakeRevenue};
|
||||
pub use weight::{FixedRateOfConcreteFungible, FixedWeightBounds, TakeRevenue, UsingComponents};
|
||||
|
||||
mod matches_fungible;
|
||||
pub use matches_fungible::{IsAbstract, IsConcrete};
|
||||
|
||||
@@ -14,19 +14,18 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sp_std::{marker::PhantomData, borrow::Borrow};
|
||||
use sp_io::hashing::blake2_256;
|
||||
use sp_runtime::traits::AccountIdConversion;
|
||||
use frame_support::traits::Get;
|
||||
use parity_scale_codec::Encode;
|
||||
use xcm::v0::{MultiLocation, NetworkId, Junction};
|
||||
use xcm_executor::traits::{InvertLocation, Convert};
|
||||
use sp_io::hashing::blake2_256;
|
||||
use sp_runtime::traits::AccountIdConversion;
|
||||
use sp_std::{borrow::Borrow, marker::PhantomData};
|
||||
use xcm::v0::{Junction, MultiLocation, NetworkId};
|
||||
use xcm_executor::traits::{Convert, InvertLocation};
|
||||
|
||||
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
|
||||
> Convert<MultiLocation, AccountId> for Account32Hash<Network, AccountId> {
|
||||
impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
|
||||
Convert<MultiLocation, AccountId> for Account32Hash<Network, AccountId>
|
||||
{
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
Ok(("multiloc", location.borrow()).using_encoded(blake2_256).into())
|
||||
}
|
||||
@@ -39,9 +38,9 @@ impl<
|
||||
/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the
|
||||
/// default value of `AccountId` (e.g. all zeros for `AccountId32`).
|
||||
pub struct ParentIsDefault<AccountId>(PhantomData<AccountId>);
|
||||
impl<
|
||||
AccountId: Default + Eq + Clone,
|
||||
> Convert<MultiLocation, AccountId> for ParentIsDefault<AccountId> {
|
||||
impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
|
||||
for ParentIsDefault<AccountId>
|
||||
{
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
if let &MultiLocation::X1(Junction::Parent) = location.borrow() {
|
||||
Ok(AccountId::default())
|
||||
@@ -60,10 +59,9 @@ impl<
|
||||
}
|
||||
|
||||
pub struct ChildParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
|
||||
impl<
|
||||
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
|
||||
AccountId: Clone,
|
||||
> Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId> {
|
||||
impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId: Clone>
|
||||
Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId>
|
||||
{
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
if let &MultiLocation::X1(Junction::Parachain(id)) = location.borrow() {
|
||||
Ok(ParaId::from(id).into_account())
|
||||
@@ -82,10 +80,9 @@ impl<
|
||||
}
|
||||
|
||||
pub struct SiblingParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
|
||||
impl<
|
||||
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
|
||||
AccountId: Clone,
|
||||
> Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId> {
|
||||
impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId: Clone>
|
||||
Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId>
|
||||
{
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
if let &MultiLocation::X2(Junction::Parent, Junction::Parachain(id)) = location.borrow() {
|
||||
Ok(ParaId::from(id).into_account())
|
||||
@@ -105,14 +102,15 @@ impl<
|
||||
|
||||
/// Extracts the `AccountId32` from the passed `location` if the network matches.
|
||||
pub struct AccountId32Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
|
||||
> Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId> {
|
||||
impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
|
||||
Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId>
|
||||
{
|
||||
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
||||
let id = match location {
|
||||
MultiLocation::X1(Junction::AccountId32 { id, network: NetworkId::Any }) => id,
|
||||
MultiLocation::X1(Junction::AccountId32 { id, network }) if &network == &Network::get() => id,
|
||||
MultiLocation::X1(Junction::AccountId32 { id, network })
|
||||
if &network == &Network::get() =>
|
||||
id,
|
||||
l => return Err(l),
|
||||
};
|
||||
Ok(id.into())
|
||||
@@ -124,14 +122,15 @@ impl<
|
||||
}
|
||||
|
||||
pub struct AccountKey20Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone,
|
||||
> Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId> {
|
||||
impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone>
|
||||
Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId>
|
||||
{
|
||||
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
||||
let key = match location {
|
||||
MultiLocation::X1(Junction::AccountKey20 { key, network: NetworkId::Any }) => key,
|
||||
MultiLocation::X1(Junction::AccountKey20 { key, network }) if &network == &Network::get() => key,
|
||||
MultiLocation::X1(Junction::AccountKey20 { key, network })
|
||||
if &network == &Network::get() =>
|
||||
key,
|
||||
l => return Err(l),
|
||||
};
|
||||
Ok(key.into())
|
||||
@@ -182,7 +181,8 @@ impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry>
|
||||
fn invert_location(location: &MultiLocation) -> MultiLocation {
|
||||
let mut ancestry = Ancestry::get();
|
||||
let mut result = location.clone();
|
||||
for (i, j) in location.iter_rev()
|
||||
for (i, j) in location
|
||||
.iter_rev()
|
||||
.map(|j| match j {
|
||||
Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild),
|
||||
_ => Junction::Parent,
|
||||
@@ -200,7 +200,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
use frame_support::parameter_types;
|
||||
use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
|
||||
use xcm::v0::{Junction::*, MultiLocation::*, NetworkId::Any};
|
||||
|
||||
fn account20() -> Junction {
|
||||
AccountKey20 { network: Any, key: Default::default() }
|
||||
@@ -224,7 +224,7 @@ mod tests {
|
||||
// output (target to source): ../../para_1/account20_default/account20_default
|
||||
#[test]
|
||||
fn inverter_works_in_tree() {
|
||||
parameter_types!{
|
||||
parameter_types! {
|
||||
pub Ancestry: MultiLocation = X3(Parachain(1), account20(), account20());
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ mod tests {
|
||||
// ^ Target
|
||||
#[test]
|
||||
fn inverter_uses_ancestry_as_inverted_location() {
|
||||
parameter_types!{
|
||||
parameter_types! {
|
||||
pub Ancestry: MultiLocation = X2(account20(), account20());
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ mod tests {
|
||||
// ^ Target
|
||||
#[test]
|
||||
fn inverter_uses_only_child_on_missing_ancestry() {
|
||||
parameter_types!{
|
||||
parameter_types! {
|
||||
pub Ancestry: MultiLocation = X1(PalletInstance(5));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
//! Various implementations for the `MatchesFungible` trait.
|
||||
|
||||
use sp_std::{marker::PhantomData, convert::TryFrom};
|
||||
use sp_runtime::traits::CheckedConversion;
|
||||
use xcm::v0::{MultiAsset, MultiLocation};
|
||||
use frame_support::traits::Get;
|
||||
use sp_runtime::traits::CheckedConversion;
|
||||
use sp_std::{convert::TryFrom, marker::PhantomData};
|
||||
use xcm::v0::{MultiAsset, MultiLocation};
|
||||
use xcm_executor::traits::MatchesFungible;
|
||||
|
||||
/// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that
|
||||
|
||||
@@ -14,26 +14,33 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell};
|
||||
pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
|
||||
pub use parity_scale_codec::{Encode, Decode};
|
||||
pub use xcm::v0::{
|
||||
SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error as XcmError,
|
||||
OriginKind, MultiLocation, Junction, opaque,
|
||||
pub use crate::{
|
||||
AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
|
||||
FixedRateOfConcreteFungible, FixedWeightBounds, LocationInverter, TakeWeightCredit,
|
||||
};
|
||||
pub use frame_support::{
|
||||
dispatch::{
|
||||
DispatchError, DispatchInfo, DispatchResultWithPostInfo, Dispatchable, Parameter, Weight,
|
||||
},
|
||||
ensure, parameter_types,
|
||||
dispatch::{Dispatchable, Parameter, Weight, DispatchError, DispatchResultWithPostInfo, DispatchInfo},
|
||||
weights::{PostDispatchInfo, GetDispatchInfo},
|
||||
sp_runtime::DispatchErrorWithPostInfo,
|
||||
traits::{Get, Contains, IsInVec},
|
||||
traits::{Contains, Get, IsInVec},
|
||||
weights::{GetDispatchInfo, PostDispatchInfo},
|
||||
};
|
||||
pub use parity_scale_codec::{Decode, Encode};
|
||||
pub use sp_std::{
|
||||
cell::RefCell,
|
||||
collections::{btree_map::BTreeMap, btree_set::BTreeSet},
|
||||
fmt::Debug,
|
||||
marker::PhantomData,
|
||||
};
|
||||
pub use xcm::v0::{
|
||||
opaque, Error as XcmError, Junction, Junction::*, MultiAsset, MultiLocation, MultiLocation::*,
|
||||
Order, OriginKind, Result as XcmResult, SendXcm, Xcm,
|
||||
};
|
||||
pub use xcm_executor::{
|
||||
Assets, Config, traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse}
|
||||
};
|
||||
pub use crate::{
|
||||
TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds,
|
||||
FixedRateOfConcreteFungible, AllowKnownQueryResponses, LocationInverter,
|
||||
traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
|
||||
Assets, Config,
|
||||
};
|
||||
|
||||
pub enum TestOrigin {
|
||||
@@ -62,20 +69,18 @@ impl Dispatchable for TestCall {
|
||||
fn dispatch(self, origin: Self::Origin) -> DispatchResultWithPostInfo {
|
||||
let mut post_info = PostDispatchInfo::default();
|
||||
post_info.actual_weight = match self {
|
||||
TestCall::OnlyRoot(_, maybe_actual)
|
||||
| TestCall::OnlySigned(_, maybe_actual, _)
|
||||
| TestCall::OnlyParachain(_, maybe_actual, _)
|
||||
| TestCall::Any(_, maybe_actual)
|
||||
=> maybe_actual,
|
||||
TestCall::OnlyRoot(_, maybe_actual) |
|
||||
TestCall::OnlySigned(_, maybe_actual, _) |
|
||||
TestCall::OnlyParachain(_, maybe_actual, _) |
|
||||
TestCall::Any(_, maybe_actual) => maybe_actual,
|
||||
};
|
||||
if match (&origin, &self) {
|
||||
(TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j))) => i == j,
|
||||
(TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j))) => i == j,
|
||||
(TestOrigin::Root, TestCall::OnlyRoot(..))
|
||||
| (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None))
|
||||
| (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None))
|
||||
| (_, TestCall::Any(..))
|
||||
=> true,
|
||||
(TestOrigin::Root, TestCall::OnlyRoot(..)) |
|
||||
(TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None)) |
|
||||
(TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None)) |
|
||||
(_, TestCall::Any(..)) => true,
|
||||
_ => false,
|
||||
} {
|
||||
Ok(post_info)
|
||||
@@ -88,13 +93,12 @@ impl Dispatchable for TestCall {
|
||||
impl GetDispatchInfo for TestCall {
|
||||
fn get_dispatch_info(&self) -> DispatchInfo {
|
||||
let weight = *match self {
|
||||
TestCall::OnlyRoot(estimate, ..)
|
||||
| TestCall::OnlyParachain(estimate, ..)
|
||||
| TestCall::OnlySigned(estimate, ..)
|
||||
| TestCall::Any(estimate, ..)
|
||||
=> estimate,
|
||||
TestCall::OnlyRoot(estimate, ..) |
|
||||
TestCall::OnlyParachain(estimate, ..) |
|
||||
TestCall::OnlySigned(estimate, ..) |
|
||||
TestCall::Any(estimate, ..) => estimate,
|
||||
};
|
||||
DispatchInfo { weight, .. Default::default() }
|
||||
DispatchInfo { weight, ..Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,11 +123,7 @@ pub fn assets(who: u64) -> Vec<MultiAsset> {
|
||||
ASSETS.with(|a| a.borrow().get(&who).map_or(vec![], |a| a.clone().into()))
|
||||
}
|
||||
pub fn add_asset(who: u64, what: MultiAsset) {
|
||||
ASSETS.with(|a| a.borrow_mut()
|
||||
.entry(who)
|
||||
.or_insert(Assets::new())
|
||||
.saturating_subsume(what)
|
||||
);
|
||||
ASSETS.with(|a| a.borrow_mut().entry(who).or_insert(Assets::new()).saturating_subsume(what));
|
||||
}
|
||||
|
||||
pub struct TestAssetTransactor;
|
||||
@@ -136,16 +136,16 @@ impl TransactAsset for TestAssetTransactor {
|
||||
|
||||
fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result<Assets, XcmError> {
|
||||
let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?;
|
||||
ASSETS.with(|a| a.borrow_mut()
|
||||
.get_mut(&who)
|
||||
.ok_or(XcmError::NotWithdrawable)?
|
||||
.try_take(what.clone())
|
||||
.map_err(|()| XcmError::NotWithdrawable)
|
||||
)
|
||||
ASSETS.with(|a| {
|
||||
a.borrow_mut()
|
||||
.get_mut(&who)
|
||||
.ok_or(XcmError::NotWithdrawable)?
|
||||
.try_take(what.clone())
|
||||
.map_err(|()| XcmError::NotWithdrawable)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
|
||||
Ok(match l {
|
||||
// Siblings at 2000+id
|
||||
@@ -164,14 +164,17 @@ pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
|
||||
|
||||
pub struct TestOriginConverter;
|
||||
impl ConvertOrigin<TestOrigin> for TestOriginConverter {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<TestOrigin, MultiLocation> {
|
||||
fn convert_origin(
|
||||
origin: MultiLocation,
|
||||
kind: OriginKind,
|
||||
) -> Result<TestOrigin, MultiLocation> {
|
||||
use OriginKind::*;
|
||||
match (kind, origin) {
|
||||
(Superuser, _) => Ok(TestOrigin::Root),
|
||||
(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
|
||||
(Native, X1(Parachain(id))) => Ok(TestOrigin::Parachain(id)),
|
||||
(Native, X1(Parent)) => Ok(TestOrigin::Relay),
|
||||
(Native, X1(AccountIndex64 {index, ..})) => Ok(TestOrigin::Signed(index)),
|
||||
(Native, X1(AccountIndex64 { index, .. })) => Ok(TestOrigin::Signed(index)),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
@@ -191,17 +194,15 @@ pub fn add_teleporter(from: MultiLocation, asset: MultiAsset) {
|
||||
pub struct TestIsReserve;
|
||||
impl FilterAssetLocation for TestIsReserve {
|
||||
fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||
IS_RESERVE.with(|r| r.borrow().get(origin)
|
||||
.map_or(false, |v| v.iter().any(|a| a.contains(asset)))
|
||||
)
|
||||
IS_RESERVE
|
||||
.with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.contains(asset))))
|
||||
}
|
||||
}
|
||||
pub struct TestIsTeleporter;
|
||||
impl FilterAssetLocation for TestIsTeleporter {
|
||||
fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||
IS_TELEPORTER.with(|r| r.borrow().get(origin)
|
||||
.map_or(false, |v| v.iter().any(|a| a.contains(asset)))
|
||||
)
|
||||
IS_TELEPORTER
|
||||
.with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.contains(asset))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,28 +224,25 @@ impl OnResponse for TestResponseHandler {
|
||||
}
|
||||
fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight {
|
||||
QUERIES.with(|q| {
|
||||
q.borrow_mut()
|
||||
.entry(query_id)
|
||||
.and_modify(|v| if matches!(*v, ResponseSlot::Expecting(..)) {
|
||||
q.borrow_mut().entry(query_id).and_modify(|v| {
|
||||
if matches!(*v, ResponseSlot::Expecting(..)) {
|
||||
*v = ResponseSlot::Received(response);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
10
|
||||
}
|
||||
}
|
||||
pub fn expect_response(query_id: u64, from: MultiLocation) {
|
||||
QUERIES.with(|q| q.borrow_mut()
|
||||
.insert(query_id, ResponseSlot::Expecting(from))
|
||||
);
|
||||
QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from)));
|
||||
}
|
||||
pub fn response(query_id: u64) -> Option<Response> {
|
||||
QUERIES.with(|q| q.borrow()
|
||||
.get(&query_id)
|
||||
.and_then(|v| match v {
|
||||
QUERIES.with(|q| {
|
||||
q.borrow().get(&query_id).and_then(|v| match v {
|
||||
ResponseSlot::Received(r) => Some(r.clone()),
|
||||
_ => None,
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
|
||||
@@ -16,21 +16,22 @@
|
||||
|
||||
//! Various implementations for `ConvertOrigin`.
|
||||
|
||||
use sp_std::{marker::PhantomData, convert::TryInto};
|
||||
use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction, BodyId, BodyPart};
|
||||
use xcm_executor::traits::{Convert, ConvertOrigin};
|
||||
use frame_support::traits::{EnsureOrigin, Get, OriginTrait, GetBacking};
|
||||
use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
|
||||
use frame_system::RawOrigin as SystemRawOrigin;
|
||||
use polkadot_parachain::primitives::IsSystem;
|
||||
use sp_std::{convert::TryInto, marker::PhantomData};
|
||||
use xcm::v0::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind};
|
||||
use xcm_executor::traits::{Convert, ConvertOrigin};
|
||||
|
||||
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
|
||||
pub struct SovereignSignedViaLocation<LocationConverter, Origin>(
|
||||
PhantomData<(LocationConverter, Origin)>
|
||||
PhantomData<(LocationConverter, Origin)>,
|
||||
);
|
||||
impl<
|
||||
LocationConverter: Convert<MultiLocation, Origin::AccountId>,
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for SovereignSignedViaLocation<LocationConverter, Origin> where Origin::AccountId: Clone {
|
||||
impl<LocationConverter: Convert<MultiLocation, Origin::AccountId>, Origin: OriginTrait>
|
||||
ConvertOrigin<Origin> for SovereignSignedViaLocation<LocationConverter, Origin>
|
||||
where
|
||||
Origin::AccountId: Clone,
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
if let OriginKind::SovereignAccount = kind {
|
||||
let location = LocationConverter::convert(origin)?;
|
||||
@@ -42,27 +43,23 @@ impl<
|
||||
}
|
||||
|
||||
pub struct ParentAsSuperuser<Origin>(PhantomData<Origin>);
|
||||
impl<
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
|
||||
impl<Origin: OriginTrait> ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) =>
|
||||
Ok(Origin::root()),
|
||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) => Ok(Origin::root()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChildSystemParachainAsSuperuser<ParaId, Origin>(PhantomData<(ParaId, Origin)>);
|
||||
impl<
|
||||
ParaId: IsSystem + From<u32>,
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for ChildSystemParachainAsSuperuser<ParaId, Origin> {
|
||||
impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
|
||||
for ChildSystemParachainAsSuperuser<ParaId, Origin>
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parachain(id)))
|
||||
if ParaId::from(id).is_system() =>
|
||||
if ParaId::from(id).is_system() =>
|
||||
Ok(Origin::root()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
@@ -70,60 +67,53 @@ impl<
|
||||
}
|
||||
|
||||
pub struct SiblingSystemParachainAsSuperuser<ParaId, Origin>(PhantomData<(ParaId, Origin)>);
|
||||
impl<
|
||||
ParaId: IsSystem + From<u32>,
|
||||
Origin: OriginTrait
|
||||
> ConvertOrigin<Origin> for SiblingSystemParachainAsSuperuser<ParaId, Origin> {
|
||||
impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
|
||||
for SiblingSystemParachainAsSuperuser<ParaId, Origin>
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Superuser, MultiLocation::X2(Junction::Parent, Junction::Parachain(id)))
|
||||
if ParaId::from(id).is_system() =>
|
||||
Ok(Origin::root()),
|
||||
(
|
||||
OriginKind::Superuser,
|
||||
MultiLocation::X2(Junction::Parent, Junction::Parachain(id)),
|
||||
) if ParaId::from(id).is_system() => Ok(Origin::root()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChildParachainAsNative<ParachainOrigin, Origin>(
|
||||
PhantomData<(ParachainOrigin, Origin)>
|
||||
);
|
||||
impl<
|
||||
ParachainOrigin: From<u32>,
|
||||
Origin: From<ParachainOrigin>,
|
||||
> ConvertOrigin<Origin> for ChildParachainAsNative<ParachainOrigin, Origin> {
|
||||
pub struct ChildParachainAsNative<ParachainOrigin, Origin>(PhantomData<(ParachainOrigin, Origin)>);
|
||||
impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Origin>
|
||||
for ChildParachainAsNative<ParachainOrigin, Origin>
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::Parachain(id)))
|
||||
=> Ok(Origin::from(ParachainOrigin::from(id))),
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::Parachain(id))) =>
|
||||
Ok(Origin::from(ParachainOrigin::from(id))),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SiblingParachainAsNative<ParachainOrigin, Origin>(
|
||||
PhantomData<(ParachainOrigin, Origin)>
|
||||
PhantomData<(ParachainOrigin, Origin)>,
|
||||
);
|
||||
impl<
|
||||
ParachainOrigin: From<u32>,
|
||||
Origin: From<ParachainOrigin>,
|
||||
> ConvertOrigin<Origin> for SiblingParachainAsNative<ParachainOrigin, Origin> {
|
||||
impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Origin>
|
||||
for SiblingParachainAsNative<ParachainOrigin, Origin>
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain(id)))
|
||||
=> Ok(Origin::from(ParachainOrigin::from(id))),
|
||||
(OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain(id))) =>
|
||||
Ok(Origin::from(ParachainOrigin::from(id))),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Our Relay-chain has a native origin given by the `Get`ter.
|
||||
pub struct RelayChainAsNative<RelayOrigin, Origin>(
|
||||
PhantomData<(RelayOrigin, Origin)>
|
||||
);
|
||||
impl<
|
||||
RelayOrigin: Get<Origin>,
|
||||
Origin,
|
||||
> ConvertOrigin<Origin> for RelayChainAsNative<RelayOrigin, Origin> {
|
||||
pub struct RelayChainAsNative<RelayOrigin, Origin>(PhantomData<(RelayOrigin, Origin)>);
|
||||
impl<RelayOrigin: Get<Origin>, Origin> ConvertOrigin<Origin>
|
||||
for RelayChainAsNative<RelayOrigin, Origin>
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::Parent)) => Ok(RelayOrigin::get()),
|
||||
@@ -132,41 +122,33 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SignedAccountId32AsNative<Network, Origin>(
|
||||
PhantomData<(Network, Origin)>
|
||||
);
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for SignedAccountId32AsNative<Network, Origin> where
|
||||
pub struct SignedAccountId32AsNative<Network, Origin>(PhantomData<(Network, Origin)>);
|
||||
impl<Network: Get<NetworkId>, Origin: OriginTrait> ConvertOrigin<Origin>
|
||||
for SignedAccountId32AsNative<Network, Origin>
|
||||
where
|
||||
Origin::AccountId: From<[u8; 32]>,
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::AccountId32 { id, network }))
|
||||
if matches!(network, NetworkId::Any) || network == Network::get()
|
||||
=> Ok(Origin::signed(id.into())),
|
||||
if matches!(network, NetworkId::Any) || network == Network::get() =>
|
||||
Ok(Origin::signed(id.into())),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SignedAccountKey20AsNative<Network, Origin>(
|
||||
PhantomData<(Network, Origin)>
|
||||
);
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
Origin: OriginTrait
|
||||
> ConvertOrigin<Origin> for SignedAccountKey20AsNative<Network, Origin> where
|
||||
pub struct SignedAccountKey20AsNative<Network, Origin>(PhantomData<(Network, Origin)>);
|
||||
impl<Network: Get<NetworkId>, Origin: OriginTrait> ConvertOrigin<Origin>
|
||||
for SignedAccountKey20AsNative<Network, Origin>
|
||||
where
|
||||
Origin::AccountId: From<[u8; 20]>,
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::AccountKey20 { key, network }))
|
||||
if matches!(network, NetworkId::Any) || network == Network::get() =>
|
||||
{
|
||||
Ok(Origin::signed(key.into()))
|
||||
}
|
||||
Ok(Origin::signed(key.into())),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
@@ -174,10 +156,9 @@ impl<
|
||||
|
||||
/// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists.
|
||||
pub struct EnsureXcmOrigin<Origin, Conversion>(PhantomData<(Origin, Conversion)>);
|
||||
impl<
|
||||
Origin: OriginTrait + Clone,
|
||||
Conversion: Convert<Origin, MultiLocation>,
|
||||
> EnsureOrigin<Origin> for EnsureXcmOrigin<Origin, Conversion> where
|
||||
impl<Origin: OriginTrait + Clone, Conversion: Convert<Origin, MultiLocation>> EnsureOrigin<Origin>
|
||||
for EnsureXcmOrigin<Origin, Conversion>
|
||||
where
|
||||
Origin::PalletsOrigin: PartialEq,
|
||||
{
|
||||
type Success = MultiLocation;
|
||||
@@ -206,15 +187,13 @@ impl<
|
||||
/// Typically used when configuring `pallet-xcm` for allowing normal accounts to dispatch an XCM from an `AccountId32`
|
||||
/// origin.
|
||||
pub struct SignedToAccountId32<Origin, AccountId, Network>(
|
||||
PhantomData<(Origin, AccountId, Network)>
|
||||
PhantomData<(Origin, AccountId, Network)>,
|
||||
);
|
||||
impl<
|
||||
Origin: OriginTrait + Clone,
|
||||
AccountId: Into<[u8; 32]>,
|
||||
Network: Get<NetworkId>,
|
||||
> Convert<Origin, MultiLocation> for SignedToAccountId32<Origin, AccountId, Network> where
|
||||
Origin::PalletsOrigin: From<SystemRawOrigin<AccountId>> +
|
||||
TryInto<SystemRawOrigin<AccountId>, Error=Origin::PalletsOrigin>
|
||||
impl<Origin: OriginTrait + Clone, AccountId: Into<[u8; 32]>, Network: Get<NetworkId>>
|
||||
Convert<Origin, MultiLocation> for SignedToAccountId32<Origin, AccountId, Network>
|
||||
where
|
||||
Origin::PalletsOrigin: From<SystemRawOrigin<AccountId>>
|
||||
+ TryInto<SystemRawOrigin<AccountId>, Error = Origin::PalletsOrigin>,
|
||||
{
|
||||
fn convert(o: Origin) -> Result<MultiLocation, Origin> {
|
||||
o.try_with_caller(|caller| match caller.try_into() {
|
||||
@@ -231,16 +210,11 @@ impl<
|
||||
///
|
||||
/// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an XCM from a
|
||||
/// `Plurality` origin.
|
||||
pub struct BackingToPlurality<Origin, COrigin, Body>(
|
||||
PhantomData<(Origin, COrigin, Body)>
|
||||
);
|
||||
impl<
|
||||
Origin: OriginTrait + Clone,
|
||||
COrigin: GetBacking,
|
||||
Body: Get<BodyId>,
|
||||
> Convert<Origin, MultiLocation> for BackingToPlurality<Origin, COrigin, Body> where
|
||||
Origin::PalletsOrigin: From<COrigin> +
|
||||
TryInto<COrigin, Error=Origin::PalletsOrigin>
|
||||
pub struct BackingToPlurality<Origin, COrigin, Body>(PhantomData<(Origin, COrigin, Body)>);
|
||||
impl<Origin: OriginTrait + Clone, COrigin: GetBacking, Body: Get<BodyId>>
|
||||
Convert<Origin, MultiLocation> for BackingToPlurality<Origin, COrigin, Body>
|
||||
where
|
||||
Origin::PalletsOrigin: From<COrigin> + TryInto<COrigin, Error = Origin::PalletsOrigin>,
|
||||
{
|
||||
fn convert(o: Origin) -> Result<MultiLocation, Origin> {
|
||||
o.try_with_caller(|caller| match caller.try_into() {
|
||||
@@ -248,9 +222,10 @@ impl<
|
||||
Some(backing) => Ok(Junction::Plurality {
|
||||
id: Body::get(),
|
||||
part: BodyPart::Fraction { nom: backing.approvals, denom: backing.eligible },
|
||||
}.into()),
|
||||
}
|
||||
.into()),
|
||||
None => Err(co.into()),
|
||||
}
|
||||
},
|
||||
Err(other) => Err(other),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use super::mock::*;
|
||||
use {MultiAsset::*, Option::None};
|
||||
use xcm::v0::{Order, NetworkId::Any, Outcome, Response, ExecuteXcm};
|
||||
use xcm_executor::{XcmExecutor, Config, traits::*};
|
||||
use super::{mock::*, *};
|
||||
use xcm::v0::{ExecuteXcm, NetworkId::Any, Order, Outcome, Response};
|
||||
use xcm_executor::{traits::*, Config, XcmExecutor};
|
||||
use MultiAsset::*;
|
||||
use Option::None;
|
||||
|
||||
#[test]
|
||||
fn basic_setup_works() {
|
||||
@@ -32,8 +32,8 @@ fn basic_setup_works() {
|
||||
assert_eq!(to_account(X1(Parachain(50))), Ok(1050));
|
||||
assert_eq!(to_account(X2(Parent, Parachain(1))), Ok(2001));
|
||||
assert_eq!(to_account(X2(Parent, Parachain(50))), Ok(2050));
|
||||
assert_eq!(to_account(X1(AccountIndex64{index:1, network:Any})), Ok(1));
|
||||
assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42));
|
||||
assert_eq!(to_account(X1(AccountIndex64 { index: 1, network: Any })), Ok(1));
|
||||
assert_eq!(to_account(X1(AccountIndex64 { index: 42, network: Any })), Ok(42));
|
||||
assert_eq!(to_account(Null), Ok(3000));
|
||||
}
|
||||
|
||||
@@ -42,10 +42,17 @@ fn weigher_should_work() {
|
||||
let mut message = opaque::Xcm::ReserveAssetDeposit {
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
|
||||
effects: vec![
|
||||
Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
|
||||
Order::BuyExecution {
|
||||
fees: All,
|
||||
weight: 0,
|
||||
debt: 30,
|
||||
halt_on_error: true,
|
||||
xcm: vec![],
|
||||
},
|
||||
Order::DepositAsset { assets: vec![All], dest: Null },
|
||||
],
|
||||
}.into();
|
||||
}
|
||||
.into();
|
||||
assert_eq!(<TestConfig as Config>::Weigher::shallow(&mut message), Ok(30));
|
||||
}
|
||||
|
||||
@@ -57,23 +64,13 @@ fn take_weight_credit_barrier_should_work() {
|
||||
};
|
||||
|
||||
let mut weight_credit = 10;
|
||||
let r = TakeWeightCredit::should_execute(
|
||||
&X1(Parent),
|
||||
true,
|
||||
&mut message,
|
||||
10,
|
||||
&mut weight_credit,
|
||||
);
|
||||
let r =
|
||||
TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(weight_credit, 0);
|
||||
|
||||
let r = TakeWeightCredit::should_execute(
|
||||
&X1(Parent),
|
||||
true,
|
||||
&mut message,
|
||||
10,
|
||||
&mut weight_credit,
|
||||
);
|
||||
let r =
|
||||
TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit);
|
||||
assert_eq!(r, Err(()));
|
||||
assert_eq!(weight_credit, 0);
|
||||
}
|
||||
@@ -85,7 +82,7 @@ fn allow_unpaid_should_work() {
|
||||
dest: Null,
|
||||
};
|
||||
|
||||
AllowUnpaidFrom::set(vec![ X1(Parent) ]);
|
||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
||||
|
||||
let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
|
||||
&X1(Parachain(1)),
|
||||
@@ -108,7 +105,7 @@ fn allow_unpaid_should_work() {
|
||||
|
||||
#[test]
|
||||
fn allow_paid_should_work() {
|
||||
AllowPaidFrom::set(vec![ X1(Parent) ]);
|
||||
AllowPaidFrom::set(vec![X1(Parent)]);
|
||||
|
||||
let mut message = opaque::Xcm::TransferAsset {
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
|
||||
@@ -127,7 +124,13 @@ fn allow_paid_should_work() {
|
||||
let mut underpaying_message = opaque::Xcm::ReserveAssetDeposit {
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
|
||||
effects: vec![
|
||||
Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
|
||||
Order::BuyExecution {
|
||||
fees: All,
|
||||
weight: 0,
|
||||
debt: 20,
|
||||
halt_on_error: true,
|
||||
xcm: vec![],
|
||||
},
|
||||
Order::DepositAsset { assets: vec![All], dest: Null },
|
||||
],
|
||||
};
|
||||
@@ -144,7 +147,13 @@ fn allow_paid_should_work() {
|
||||
let mut paying_message = opaque::Xcm::ReserveAssetDeposit {
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
|
||||
effects: vec![
|
||||
Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
|
||||
Order::BuyExecution {
|
||||
fees: All,
|
||||
weight: 0,
|
||||
debt: 30,
|
||||
halt_on_error: true,
|
||||
xcm: vec![],
|
||||
},
|
||||
Order::DepositAsset { assets: vec![All], dest: Null },
|
||||
],
|
||||
};
|
||||
@@ -170,79 +179,88 @@ fn allow_paid_should_work() {
|
||||
|
||||
#[test]
|
||||
fn paying_reserve_deposit_should_work() {
|
||||
AllowPaidFrom::set(vec![ X1(Parent) ]);
|
||||
AllowPaidFrom::set(vec![X1(Parent)]);
|
||||
add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) });
|
||||
WeightPrice::set((X1(Parent), 1_000_000_000_000));
|
||||
|
||||
let origin = X1(Parent);
|
||||
let message = Xcm::<TestCall>::ReserveAssetDeposit {
|
||||
assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
|
||||
effects: vec![
|
||||
Order::<TestCall>::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
|
||||
Order::<TestCall>::DepositAsset { assets: vec![ All ], dest: Null },
|
||||
Order::<TestCall>::BuyExecution {
|
||||
fees: All,
|
||||
weight: 0,
|
||||
debt: 30,
|
||||
halt_on_error: true,
|
||||
xcm: vec![],
|
||||
},
|
||||
Order::<TestCall>::DepositAsset { assets: vec![All], dest: Null },
|
||||
],
|
||||
};
|
||||
let weight_limit = 50;
|
||||
let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
|
||||
assert_eq!(r, Outcome::Complete(30));
|
||||
assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]);
|
||||
assert_eq!(assets(3000), vec![ConcreteFungible { id: X1(Parent), amount: 70 }]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transfer_should_work() {
|
||||
// we'll let them have message execution for free.
|
||||
AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
|
||||
AllowUnpaidFrom::set(vec![X1(Parachain(1))]);
|
||||
// Child parachain #1 owns 1000 tokens held by us in reserve.
|
||||
add_asset(1001, ConcreteFungible { id: Null, amount: 1000 });
|
||||
// They want to transfer 100 of them to their sibling parachain #2
|
||||
let r = XcmExecutor::<TestConfig>::execute_xcm(
|
||||
X1(Parachain(1)),
|
||||
Xcm::TransferAsset {
|
||||
assets: vec![ ConcreteFungible { id: Null, amount: 100 } ],
|
||||
dest: X1(AccountIndex64{index:3, network:Any}),
|
||||
assets: vec![ConcreteFungible { id: Null, amount: 100 }],
|
||||
dest: X1(AccountIndex64 { index: 3, network: Any }),
|
||||
},
|
||||
50,
|
||||
);
|
||||
assert_eq!(r, Outcome::Complete(10));
|
||||
assert_eq!(assets(3), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
|
||||
assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null, amount: 900 } ]);
|
||||
assert_eq!(assets(3), vec![ConcreteFungible { id: Null, amount: 100 }]);
|
||||
assert_eq!(assets(1001), vec![ConcreteFungible { id: Null, amount: 900 }]);
|
||||
assert_eq!(sent_xcm(), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserve_transfer_should_work() {
|
||||
AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
|
||||
AllowUnpaidFrom::set(vec![X1(Parachain(1))]);
|
||||
// Child parachain #1 owns 1000 tokens held by us in reserve.
|
||||
add_asset(1001, ConcreteFungible { id: Null, amount: 1000 });
|
||||
// The remote account owned by gav.
|
||||
let three = X1(AccountIndex64{index:3, network:Any});
|
||||
let three = X1(AccountIndex64 { index: 3, network: Any });
|
||||
|
||||
// They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2
|
||||
// and let them know to hand it to account #3.
|
||||
let r = XcmExecutor::<TestConfig>::execute_xcm(
|
||||
X1(Parachain(1)),
|
||||
Xcm::TransferReserveAsset {
|
||||
assets: vec![ ConcreteFungible { id: Null, amount: 100 } ],
|
||||
assets: vec![ConcreteFungible { id: Null, amount: 100 }],
|
||||
dest: X1(Parachain(2)),
|
||||
effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ],
|
||||
effects: vec![Order::DepositAsset { assets: vec![All], dest: three.clone() }],
|
||||
},
|
||||
50,
|
||||
);
|
||||
assert_eq!(r, Outcome::Complete(10));
|
||||
|
||||
assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
|
||||
assert_eq!(sent_xcm(), vec![(
|
||||
X1(Parachain(2)),
|
||||
Xcm::ReserveAssetDeposit {
|
||||
assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
|
||||
effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ],
|
||||
})
|
||||
]);
|
||||
assert_eq!(assets(1002), vec![ConcreteFungible { id: Null, amount: 100 }]);
|
||||
assert_eq!(
|
||||
sent_xcm(),
|
||||
vec![(
|
||||
X1(Parachain(2)),
|
||||
Xcm::ReserveAssetDeposit {
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
|
||||
effects: vec![Order::DepositAsset { assets: vec![All], dest: three }],
|
||||
}
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transacting_should_work() {
|
||||
AllowUnpaidFrom::set(vec![ X1(Parent) ]);
|
||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
||||
|
||||
let origin = X1(Parent);
|
||||
let message = Xcm::<TestCall>::Transact {
|
||||
@@ -257,7 +275,7 @@ fn transacting_should_work() {
|
||||
|
||||
#[test]
|
||||
fn transacting_should_respect_max_weight_requirement() {
|
||||
AllowUnpaidFrom::set(vec![ X1(Parent) ]);
|
||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
||||
|
||||
let origin = X1(Parent);
|
||||
let message = Xcm::<TestCall>::Transact {
|
||||
@@ -272,7 +290,7 @@ fn transacting_should_respect_max_weight_requirement() {
|
||||
|
||||
#[test]
|
||||
fn transacting_should_refund_weight() {
|
||||
AllowUnpaidFrom::set(vec![ X1(Parent) ]);
|
||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
||||
|
||||
let origin = X1(Parent);
|
||||
let message = Xcm::<TestCall>::Transact {
|
||||
@@ -287,30 +305,34 @@ fn transacting_should_refund_weight() {
|
||||
|
||||
#[test]
|
||||
fn paid_transacting_should_refund_payment_for_unused_weight() {
|
||||
let one = X1(AccountIndex64{index:1, network:Any});
|
||||
AllowPaidFrom::set(vec![ one.clone() ]);
|
||||
let one = X1(AccountIndex64 { index: 1, network: Any });
|
||||
AllowPaidFrom::set(vec![one.clone()]);
|
||||
add_asset(1, ConcreteFungible { id: X1(Parent), amount: 100 });
|
||||
WeightPrice::set((X1(Parent), 1_000_000_000_000));
|
||||
|
||||
let origin = one.clone();
|
||||
let message = Xcm::<TestCall>::WithdrawAsset {
|
||||
assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], // enough for 100 units of weight.
|
||||
assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], // enough for 100 units of weight.
|
||||
effects: vec![
|
||||
Order::<TestCall>::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![
|
||||
Xcm::<TestCall>::Transact {
|
||||
Order::<TestCall>::BuyExecution {
|
||||
fees: All,
|
||||
weight: 70,
|
||||
debt: 30,
|
||||
halt_on_error: true,
|
||||
xcm: vec![Xcm::<TestCall>::Transact {
|
||||
origin_type: OriginKind::Native,
|
||||
require_weight_at_most: 60,
|
||||
// call estimated at 70 but only takes 10.
|
||||
call: TestCall::Any(60, Some(10)).encode().into(),
|
||||
}
|
||||
] },
|
||||
Order::<TestCall>::DepositAsset { assets: vec![ All ], dest: one.clone() },
|
||||
}],
|
||||
},
|
||||
Order::<TestCall>::DepositAsset { assets: vec![All], dest: one.clone() },
|
||||
],
|
||||
};
|
||||
let weight_limit = 100;
|
||||
let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
|
||||
assert_eq!(r, Outcome::Complete(50));
|
||||
assert_eq!(assets(1), vec![ ConcreteFungible { id: X1(Parent), amount: 50 } ]);
|
||||
assert_eq!(assets(1), vec![ConcreteFungible { id: X1(Parent), amount: 50 }]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -320,11 +342,8 @@ fn prepaid_result_of_query_should_get_free_execution() {
|
||||
// We put this in manually here, but normally this would be done at the point of crafting the message.
|
||||
expect_response(query_id, origin.clone());
|
||||
|
||||
let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]);
|
||||
let message = Xcm::<TestCall>::QueryResponse {
|
||||
query_id,
|
||||
response: the_response.clone(),
|
||||
};
|
||||
let the_response = Response::Assets(vec![ConcreteFungible { id: X1(Parent), amount: 100 }]);
|
||||
let message = Xcm::<TestCall>::QueryResponse { query_id, response: the_response.clone() };
|
||||
let weight_limit = 10;
|
||||
|
||||
// First time the response gets through since we're expecting it...
|
||||
|
||||
@@ -14,27 +14,32 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sp_std::{result::Result, marker::PhantomData, convert::TryInto};
|
||||
use frame_support::{
|
||||
traits::{tokens::currency::Currency as CurrencyT, Get, OnUnbalanced as OnUnbalancedT},
|
||||
weights::{GetDispatchInfo, Weight, WeightToFeePolynomial},
|
||||
};
|
||||
use parity_scale_codec::Decode;
|
||||
use xcm::v0::{Xcm, Order, MultiAsset, MultiLocation, Error};
|
||||
use sp_runtime::traits::{Zero, Saturating, SaturatedConversion};
|
||||
use frame_support::traits::{Get, OnUnbalanced as OnUnbalancedT, tokens::currency::Currency as CurrencyT};
|
||||
use frame_support::weights::{Weight, GetDispatchInfo, WeightToFeePolynomial};
|
||||
use xcm_executor::{Assets, traits::{WeightBounds, WeightTrader}};
|
||||
use sp_runtime::traits::{SaturatedConversion, Saturating, Zero};
|
||||
use sp_std::{convert::TryInto, marker::PhantomData, result::Result};
|
||||
use xcm::v0::{Error, MultiAsset, MultiLocation, Order, Xcm};
|
||||
use xcm_executor::{
|
||||
traits::{WeightBounds, WeightTrader},
|
||||
Assets,
|
||||
};
|
||||
|
||||
pub struct FixedWeightBounds<T, C>(PhantomData<(T, C)>);
|
||||
impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeightBounds<T, C> {
|
||||
fn shallow(message: &mut Xcm<C>) -> Result<Weight, ()> {
|
||||
Ok(match message {
|
||||
Xcm::Transact { call, .. } => {
|
||||
call.ensure_decoded()?.get_dispatch_info().weight.saturating_add(T::get())
|
||||
}
|
||||
Xcm::RelayedFrom { ref mut message, .. } => T::get().saturating_add(Self::shallow(message.as_mut())?),
|
||||
Xcm::WithdrawAsset { effects, .. }
|
||||
| Xcm::ReserveAssetDeposit { effects, .. }
|
||||
| Xcm::TeleportAsset { effects, .. }
|
||||
=> {
|
||||
let inner: Weight = effects.iter_mut()
|
||||
Xcm::Transact { call, .. } =>
|
||||
call.ensure_decoded()?.get_dispatch_info().weight.saturating_add(T::get()),
|
||||
Xcm::RelayedFrom { ref mut message, .. } =>
|
||||
T::get().saturating_add(Self::shallow(message.as_mut())?),
|
||||
Xcm::WithdrawAsset { effects, .. } |
|
||||
Xcm::ReserveAssetDeposit { effects, .. } |
|
||||
Xcm::TeleportAsset { effects, .. } => {
|
||||
let inner: Weight = effects
|
||||
.iter_mut()
|
||||
.map(|effect| match effect {
|
||||
Order::BuyExecution { .. } => {
|
||||
// On success, execution of this will result in more weight being consumed but
|
||||
@@ -45,28 +50,29 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
|
||||
T::get()
|
||||
},
|
||||
_ => T::get(),
|
||||
}).sum();
|
||||
})
|
||||
.sum();
|
||||
T::get().saturating_add(inner)
|
||||
}
|
||||
},
|
||||
_ => T::get(),
|
||||
})
|
||||
}
|
||||
fn deep(message: &mut Xcm<C>) -> Result<Weight, ()> {
|
||||
Ok(match message {
|
||||
Xcm::RelayedFrom { ref mut message, .. } => Self::deep(message.as_mut())?,
|
||||
Xcm::WithdrawAsset { effects, .. }
|
||||
| Xcm::ReserveAssetDeposit { effects, .. }
|
||||
| Xcm::TeleportAsset { effects, .. }
|
||||
=> {
|
||||
Xcm::WithdrawAsset { effects, .. } |
|
||||
Xcm::ReserveAssetDeposit { effects, .. } |
|
||||
Xcm::TeleportAsset { effects, .. } => {
|
||||
let mut extra = 0;
|
||||
for effect in effects.iter_mut() {
|
||||
match effect {
|
||||
Order::BuyExecution { xcm, .. } => {
|
||||
Order::BuyExecution { xcm, .. } =>
|
||||
for message in xcm.iter_mut() {
|
||||
extra.saturating_accrue(Self::shallow(message)?.saturating_add(Self::deep(message)?));
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
extra.saturating_accrue(
|
||||
Self::shallow(message)?.saturating_add(Self::deep(message)?),
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
extra
|
||||
@@ -92,12 +98,17 @@ impl TakeRevenue for () {
|
||||
///
|
||||
/// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for
|
||||
/// one second of weight.
|
||||
pub struct FixedRateOfConcreteFungible<
|
||||
T: Get<(MultiLocation, u128)>,
|
||||
R: TakeRevenue,
|
||||
>(Weight, u128, PhantomData<(T, R)>);
|
||||
impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOfConcreteFungible<T, R> {
|
||||
fn new() -> Self { Self(0, 0, PhantomData) }
|
||||
pub struct FixedRateOfConcreteFungible<T: Get<(MultiLocation, u128)>, R: TakeRevenue>(
|
||||
Weight,
|
||||
u128,
|
||||
PhantomData<(T, R)>,
|
||||
);
|
||||
impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader
|
||||
for FixedRateOfConcreteFungible<T, R>
|
||||
{
|
||||
fn new() -> Self {
|
||||
Self(0, 0, PhantomData)
|
||||
}
|
||||
|
||||
fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
|
||||
let (id, units_per_second) = T::get();
|
||||
@@ -131,20 +142,27 @@ impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> Drop for FixedRateOfConcrete
|
||||
/// Weight trader which uses the `TransactionPayment` pallet to set the right price for weight and then
|
||||
/// places any weight bought into the right account.
|
||||
pub struct UsingComponents<
|
||||
WeightToFee: WeightToFeePolynomial<Balance=Currency::Balance>,
|
||||
WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
|
||||
AssetId: Get<MultiLocation>,
|
||||
AccountId,
|
||||
Currency: CurrencyT<AccountId>,
|
||||
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
|
||||
>(Weight, Currency::Balance, PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>);
|
||||
>(
|
||||
Weight,
|
||||
Currency::Balance,
|
||||
PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
|
||||
);
|
||||
impl<
|
||||
WeightToFee: WeightToFeePolynomial<Balance=Currency::Balance>,
|
||||
AssetId: Get<MultiLocation>,
|
||||
AccountId,
|
||||
Currency: CurrencyT<AccountId>,
|
||||
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
|
||||
> WeightTrader for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced> {
|
||||
fn new() -> Self { Self(0, Zero::zero(), PhantomData) }
|
||||
WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
|
||||
AssetId: Get<MultiLocation>,
|
||||
AccountId,
|
||||
Currency: CurrencyT<AccountId>,
|
||||
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
|
||||
> WeightTrader for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
|
||||
{
|
||||
fn new() -> Self {
|
||||
Self(0, Zero::zero(), PhantomData)
|
||||
}
|
||||
|
||||
fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
|
||||
let amount = WeightToFee::calc(&weight);
|
||||
@@ -163,21 +181,19 @@ impl<
|
||||
let amount = WeightToFee::calc(&weight);
|
||||
self.0 -= weight;
|
||||
self.1 = self.1.saturating_sub(amount);
|
||||
let result = MultiAsset::ConcreteFungible {
|
||||
amount: amount.saturated_into(),
|
||||
id: AssetId::get(),
|
||||
};
|
||||
let result =
|
||||
MultiAsset::ConcreteFungible { amount: amount.saturated_into(), id: AssetId::get() };
|
||||
result
|
||||
}
|
||||
|
||||
}
|
||||
impl<
|
||||
WeightToFee: WeightToFeePolynomial<Balance=Currency::Balance>,
|
||||
AssetId: Get<MultiLocation>,
|
||||
AccountId,
|
||||
Currency: CurrencyT<AccountId>,
|
||||
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
|
||||
> Drop for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced> {
|
||||
WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
|
||||
AssetId: Get<MultiLocation>,
|
||||
AccountId,
|
||||
Currency: CurrencyT<AccountId>,
|
||||
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
|
||||
> Drop for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
OnUnbalanced::on_unbalanced(Currency::issue(self.1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user