Statemint Reserve Asset Transfer (#552)

* add AssetId type alias in statemint-common

* add FungiblesAdapter to allow for asset transactions via XCM

* use custom Polkadot

* fix FungiblesAdapter usage and add CheckingAccount

* update deps

* remove polkadot overrides

* update deps

* pull NonZeroIssuance struct into common + add FungiblesTransactor to Statemine and Westmint

* remove unnecessary tuple wrapping + adjust asset transactor comments

* accept statemint as reserve in rococo test parachain

* adjust parachain config (add Statemint as reserve)

* add test and docs for AssetsFrom

* cargo fmt

Co-authored-by: Ricardo Rius <ricardo@parity.io>
Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Alexander Popiak
2021-10-05 11:35:03 +02:00
committed by GitHub
parent edd029b3d4
commit caa8b8172b
9 changed files with 237 additions and 51 deletions
+2
View File
@@ -39,6 +39,8 @@ pallet-transaction-payment = { git = "https://github.com/paritytech/substrate",
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
parachains-common = { path = "../parachains-common", default-features = false }
# Cumulus dependencies
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
+57 -6
View File
@@ -45,7 +45,10 @@ pub use frame_support::{
},
StorageValue,
};
use frame_system::limits::{BlockLength, BlockWeights};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureOneOf, EnsureRoot,
};
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -53,6 +56,13 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_runtime::BuildStorage;
pub use sp_runtime::{Perbill, Permill};
use parachains_common::{
impls::{AssetsFrom, NonZeroIssuance},
AssetId,
};
use xcm_builder::{AsPrefixedGeneralIndex, ConvertedConcreteAssetId, FungiblesAdapter};
use xcm_executor::traits::JustTry;
// XCM imports
use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough};
use polkadot_parachain::primitives::Sibling;
@@ -258,6 +268,7 @@ parameter_types! {
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
}
/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
@@ -273,7 +284,7 @@ pub type LocationToAccountId = (
);
/// Means for transacting assets on this chain.
pub type LocalAssetTransactor = CurrencyAdapter<
pub type CurrencyTransactor = CurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching the given location or name:
@@ -286,6 +297,30 @@ pub type LocalAssetTransactor = CurrencyAdapter<
(),
>;
/// Means for transacting assets besides the native currency on this chain.
pub type FungiblesTransactor = FungiblesAdapter<
// Use this fungibles implementation:
Assets,
// Use this currency when it is a fungible asset matching the given location or name:
ConvertedConcreteAssetId<
AssetId,
u64,
AsPrefixedGeneralIndex<StatemintLocation, AssetId, JustTry>,
JustTry,
>,
// Convert an XCM MultiLocation into a local account id:
LocationToAccountId,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
AccountId,
// We only want to allow teleports of known assets. We use non-zero issuance as an indication
// that this asset is known.
NonZeroIssuance<AccountId, Assets>,
// The account to use for tracking teleports.
CheckingAccount,
>;
/// Means for transacting assets on this chain.
pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor);
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
/// biases the kind of local `Origin` it will become.
@@ -324,22 +359,34 @@ match_type! {
MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }
};
}
match_type! {
pub type Statemint: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: X1(Parachain(1000)) }
};
}
pub type Barrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
AllowUnpaidExecutionFrom<ParentOrParentsUnitPlurality>,
// ^^^ Parent & its unit plurality gets free execution
AllowUnpaidExecutionFrom<Statemint>,
);
parameter_types! {
pub StatemintLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000)));
}
pub type Reserves = (NativeAsset, AssetsFrom<StatemintLocation>);
pub struct XcmConfig;
impl Config for XcmConfig {
type Call = Call;
type XcmSender = XcmRouter;
// How to withdraw and deposit an asset.
type AssetTransactor = LocalAssetTransactor;
type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsReserve = Reserves;
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of ROC
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
@@ -416,12 +463,16 @@ parameter_types! {
}
/// A majority of the Unit body from Rococo over XCM is our required administration origin.
pub type AdminOrigin = EnsureXcm<IsMajorityOfBody<RocLocation, UnitBody>>;
pub type AdminOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
EnsureXcm<IsMajorityOfBody<RocLocation, UnitBody>>,
>;
impl pallet_assets::Config for Runtime {
type Event = Event;
type Balance = u64;
type AssetId = u32;
type AssetId = AssetId;
type Currency = Balances;
type ForceOrigin = AdminOrigin;
type AssetDeposit = AssetDeposit;