mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 22:11:02 +00:00
pallet-xcm: add new extrinsic for asset transfers using explicit XCM transfer types (#3695)
# Description Add `transfer_assets_using()` for transferring assets from local chain to destination chain using explicit XCM transfer types such as: - `TransferType::LocalReserve`: transfer assets to sovereign account of destination chain and forward a notification XCM to `dest` to mint and deposit reserve-based assets to `beneficiary`. - `TransferType::DestinationReserve`: burn local assets and forward a notification to `dest` chain to withdraw the reserve assets from this chain's sovereign account and deposit them to `beneficiary`. - `TransferType::RemoteReserve(reserve)`: burn local assets, forward XCM to `reserve` chain to move reserves from this chain's SA to `dest` chain's SA, and forward another XCM to `dest` to mint and deposit reserve-based assets to `beneficiary`. Typically the remote `reserve` is Asset Hub. - `TransferType::Teleport`: burn local assets and forward XCM to `dest` chain to mint/teleport assets and deposit them to `beneficiary`. By default, an asset's reserve is its origin chain. But sometimes we may want to explicitly use another chain as reserve (as long as allowed by runtime `IsReserve` filter). This is very helpful for transferring assets with multiple configured reserves (such as Asset Hub ForeignAssets), when the transfer strictly depends on the used reserve. E.g. For transferring Foreign Assets over a bridge, Asset Hub must be used as the reserve location. # Example usage scenarios ## Transfer bridged ethereum ERC20-tokenX between ecosystem parachains. ERC20-tokenX is registered on AssetHub as a ForeignAsset by the Polkadot<>Ethereum bridge (Snowbridge). Its asset_id is something like `(parents:2, (GlobalConsensus(Ethereum), Address(tokenX_contract)))`. Its _original_ reserve is Ethereum (only we can't use Ethereum as a reserve in local transfers); but, since tokenX is also registered on AssetHub as a ForeignAsset, we can use AssetHub as a reserve. With this PR we can transfer tokenX from ParaA to ParaB while using AssetHub as a reserve. ## Transfer AssetHub ForeignAssets between parachains AssetA created on ParaA but also registered as foreign asset on Asset Hub. Can use AssetHub as a reserve. And all of the above can be done while still controlling transfer type for `fees` so mixing assets in same transfer is supported. # Tests Added integration tests for showcasing: - transferring local (not bridged) assets from parachain over bridge using local Asset Hub reserve, - transferring foreign assets from parachain to Asset Hub, - transferring foreign assets from Asset Hub to parachain, - transferring foreign assets from parachain to parachain using local Asset Hub reserve. --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: command-bot <>
This commit is contained in:
@@ -113,17 +113,14 @@ impl<UniversalLocation: Get<InteriorLocation>, Reserves: ContainsPair<Asset, Loc
|
||||
);
|
||||
|
||||
// check remote origin
|
||||
let _ = match ensure_is_remote(universal_source.clone(), origin.clone()) {
|
||||
Ok(devolved) => devolved,
|
||||
Err(_) => {
|
||||
log::trace!(
|
||||
target: "xcm::contains",
|
||||
"IsTrustedBridgedReserveLocationForConcreteAsset origin: {:?} is not remote to the universal_source: {:?}",
|
||||
origin, universal_source
|
||||
);
|
||||
return false
|
||||
},
|
||||
};
|
||||
if ensure_is_remote(universal_source.clone(), origin.clone()).is_err() {
|
||||
log::trace!(
|
||||
target: "xcm::contains",
|
||||
"IsTrustedBridgedReserveLocationForConcreteAsset origin: {:?} is not remote to the universal_source: {:?}",
|
||||
origin, universal_source
|
||||
);
|
||||
return false
|
||||
}
|
||||
|
||||
// check asset according to the configured reserve locations
|
||||
Reserves::contains(asset, origin)
|
||||
|
||||
@@ -58,9 +58,16 @@ parameter_types! {
|
||||
pub const RelayLocation: Location = Location::parent();
|
||||
// Local native currency which is stored in `pallet_balances``
|
||||
pub const PenpalNativeCurrency: Location = Location::here();
|
||||
pub const RelayNetwork: Option<NetworkId> = None;
|
||||
// The Penpal runtime is utilized for testing with various environment setups.
|
||||
// This storage item allows us to customize the `NetworkId` where Penpal is deployed.
|
||||
// By default, it is set to `NetworkId::Rococo` and can be changed using `System::set_storage`.
|
||||
pub storage RelayNetworkId: NetworkId = NetworkId::Westend;
|
||||
pub RelayNetwork: Option<NetworkId> = Some(RelayNetworkId::get());
|
||||
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into();
|
||||
pub UniversalLocation: InteriorLocation = [
|
||||
GlobalConsensus(RelayNetworkId::get()),
|
||||
Parachain(ParachainInfo::parachain_id().into())
|
||||
].into();
|
||||
pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user