While looking at the AHM migration guide and the corresponding tests, I didn't find a test for the case of DOT transfer between two non-reserve chains using pallet-xcm's transfer_assets extrinsic (which should deduce the reserve location automatically).
I see that the tests directly execute XCM programs. However, programs are usually created by extrinsics, such as transfer_assets.
From the current code, I conclude that after AHM, when transferring DOT from Parachain A to Parachain B using polkadotXcm.transferAssets, Parachain A won't be able to deduce the reserve location:
|
let transfer_type = |
|
T::XcmExecutor::determine_for(&asset, dest).map_err(Error::<T>::from)?; |
|
pub trait XcmAssetTransfers { |
|
/// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning |
|
/// reserve-based-transfers are to be used for assets matching this filter. |
|
type IsReserve: ContainsPair<Asset, Location>; |
|
|
|
/// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are |
|
/// to be used for assets matching this filter. |
|
type IsTeleporter: ContainsPair<Asset, Location>; |
|
|
|
/// How to withdraw and deposit an asset. |
|
type AssetTransactor: TransactAsset; |
|
|
|
/// Determine transfer type to be used for transferring `asset` from local chain to `dest`. |
|
fn determine_for(asset: &Asset, dest: &Location) -> Result<TransferType, Error> { |
|
if Self::IsTeleporter::contains(asset, dest) { |
|
// we trust destination for teleporting asset |
|
return Ok(TransferType::Teleport) |
|
} else if Self::IsReserve::contains(asset, dest) { |
|
// we trust destination as asset reserve location |
|
return Ok(TransferType::DestinationReserve) |
|
} |
|
|
|
// try to determine reserve location based on asset id/location |
|
let asset_location = asset.id.0.chain_location(); |
|
if asset_location == Location::here() || |
|
Self::IsTeleporter::contains(asset, &asset_location) |
|
{ |
|
// if the asset is local, then it's a local reserve |
|
// it's also a local reserve if the asset's location is not `here` but it's a location |
|
// where it can be teleported to `here` => local reserve |
|
Ok(TransferType::LocalReserve) |
|
} else if Self::IsReserve::contains(asset, &asset_location) { |
|
// remote location that is recognized as reserve location for asset |
|
Ok(TransferType::RemoteReserve(asset_location.into())) |
|
} else { |
|
// remote location that is not configured either as teleporter or reserve => cannot |
|
// determine asset reserve |
|
Err(Error::UnknownReserve) |
|
} |
|
} |
|
} |
Do we have a test for that?
If the problem does exist, a possible solution would be to have a ReserveProvider associated type in the XcmAssetTransfers trait, similar to the ORML pallet-xtokens:
https://github.com/open-web3-stack/open-runtime-module-library/blob/2fd6442fc9b03717e491e82b9d8754a863e41c9a/xtokens/src/lib.rs#L130-L132
CC @acatangiu @franciscoaguirre @xlc
While looking at the AHM migration guide and the corresponding tests, I didn't find a test for the case of DOT transfer between two non-reserve chains using pallet-xcm's
transfer_assetsextrinsic (which should deduce the reserve location automatically).I see that the tests directly execute XCM programs. However, programs are usually created by extrinsics, such as
transfer_assets.From the current code, I conclude that after AHM, when transferring DOT from Parachain A to Parachain B using
polkadotXcm.transferAssets, Parachain A won't be able to deduce the reserve location:polkadot-sdk/polkadot/xcm/pallet-xcm/src/lib.rs
Lines 1990 to 1991 in 0447d26
polkadot-sdk/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs
Lines 45 to 85 in 3515d4a
Do we have a test for that?
If the problem does exist, a possible solution would be to have a
ReserveProviderassociated type in theXcmAssetTransferstrait, similar to the ORML pallet-xtokens:https://github.com/open-web3-stack/open-runtime-module-library/blob/2fd6442fc9b03717e491e82b9d8754a863e41c9a/xtokens/src/lib.rs#L130-L132
CC @acatangiu @franciscoaguirre @xlc