Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add selfreserve cross chain possibility to moonriver
  • Loading branch information
girazoki committed Jan 31, 2022
commit dd1d63c47264c137573a545432492b7022a4b87f
88 changes: 83 additions & 5 deletions runtime/moonriver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,28 @@ parameter_types! {
pub OperationalFeeMultiplier: u8 = 5;
}

pub struct WeightToFee;
impl WeightToFeePolynomial for WeightToFee {
type Balance = Balance;

/// Return a vec of coefficients. Here we just use one coefficient and reduce it to a constant
/// modifier in order to closely match Ethereum-based fees.
///
/// Calculation, per the documentation in `frame_support`:
///
/// ```ignore
/// coeff_integer * x^(degree) + coeff_frac * x^(degree)
/// ```
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
smallvec![WeightToFeeCoefficient {
degree: 1,
coeff_frac: Perbill::zero(),
coeff_integer: currency::WEIGHT_FEE,
negative: false,
}]
}
}

impl pallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees<Runtime>>;
type TransactionByteFee = TransactionByteFee;
Expand Down Expand Up @@ -948,16 +970,34 @@ parameter_types! {
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
// The ancestry, defines the multilocation describing this consensus system
pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
// Self Reserve location, defines the multilocation identifiying the self-reserve currency
// Old Self Reserve location, defines the multilocation identifiying the self-reserve currency
// This is used to match it against our Balances pallet when we receive such a MultiLocation
// (Parent, Self Para Id, Self Balances pallet index)
pub SelfReserve: MultiLocation = MultiLocation {
// This is the old anchoring way
pub OldAnchoringSelfReserve: MultiLocation = MultiLocation {
parents:1,
interior: Junctions::X2(
Parachain(ParachainInfo::parachain_id().into()),
PalletInstance(<Runtime as frame_system::Config>::PalletInfo::index::<Balances>().unwrap() as u8)
)
};
// Bew Self Reserve location, defines the multilocation identifiying the self-reserve currency
// This is used to match it also against our Balances pallet when we receive such
// a MultiLocation: (Self Balances pallet index)
// This is the new anchoring way
pub NewAnchoringSelfReserve: MultiLocation = MultiLocation {
parents:0,
interior: Junctions::X1(
PalletInstance(<Runtime as frame_system::Config>::PalletInfo::index::<Balances>().unwrap() as u8)
)
};

// The Locations we accept to refer to our own currency. We need to support both pre and
// post 0.9.16 versions, hence the reason for this being a Vec
pub SelfReserveRepresentations: Vec<MultiLocation> = vec![
OldAnchoringSelfReserve::get(),
NewAnchoringSelfReserve::get()
];
}

/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
Expand Down Expand Up @@ -996,10 +1036,24 @@ pub type FungiblesTransactor = FungiblesAdapter<
(),
>;

pub type LocalAssetTransactor = XcmCurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching any of the locations in
// SelfReserveRepresentations
xcm_primitives::MultiIsConcrete<SelfReserveRepresentations>,
// We can convert the MultiLocations with our converter above:
LocationToAccountId,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
AccountId,
// We dont allow teleport
(),
>;

// We use only fungiblesAdapter transactor for now
// The idea is that we only accept the relay token, hence no need to handle the local token
// As long as this does not contain the local transactor, we are good
pub type AssetTransactors = FungiblesTransactor;
pub type AssetTransactors = (LocalAssetTransactor, 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
Expand Down Expand Up @@ -1076,9 +1130,28 @@ impl xcm_executor::Config for XcmExecutorConfig {
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = XcmBarrier;
type Weigher = XcmWeigher;
// We use three traders
// When we receive either representation of the self-reserve asset,
// we use UsingComponents and the local way of handling fees
// When we receive a non-reserve asset, we use AssetManager to fetch how many
// units per second we should charge
type Trader = FirstAssetTrader<AssetType, AssetManager, XcmFeesToAccount>;
type Trader = (
UsingComponents<
WeightToFee,
OldAnchoringSelfReserve,
AccountId,
Balances,
DealWithFees<Runtime>,
>,
UsingComponents<
WeightToFee,
NewAnchoringSelfReserve,
AccountId,
Balances,
DealWithFees<Runtime>,
>,
FirstAssetTrader<AssetType, AssetManager, XcmFeesToAccount>,
);
type ResponseHandler = PolkadotXcm;
type SubscriptionService = PolkadotXcm;
type AssetTrap = PolkadotXcm;
Expand Down Expand Up @@ -1350,8 +1423,13 @@ where
{
fn convert(currency: CurrencyId) -> Option<MultiLocation> {
match currency {
// For now (and until we upgrade to 0.9.16 is adapted) we need to use the old anchoring
// here
// This is not a problem in either cases, since the view of the destination chain
// does not change
// TODO! change this to NewAnchoringSelfReserve once we uprade to 0.9.16
CurrencyId::SelfReserve => {
let multi: MultiLocation = SelfReserve::get();
let multi: MultiLocation = OldAnchoringSelfReserve::get();
Some(multi)
}
CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(),
Expand Down
68 changes: 62 additions & 6 deletions runtime/moonriver/tests/xcm_mock/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,22 @@ pub type FungiblesTransactor = FungiblesAdapter<
(),
>;

pub type LocalAssetTransactor = XcmCurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching any of the locations in
// SelfReserveRepresentations
xcm_primitives::MultiIsConcrete<SelfReserveRepresentations>,
// We can convert the MultiLocations with our converter above:
LocationToAccountId,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
AccountId,
// We dont allow teleport
(),
>;

// These will be our transactors
pub type AssetTransactors = FungiblesTransactor;
pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor);
pub type XcmRouter = super::ParachainXcmRouter<MsgQueue>;

pub type Barrier = (
Expand Down Expand Up @@ -230,20 +244,49 @@ pub type XcmFeesToAccount_ = xcm_primitives::XcmFeesToAccount<
parameter_types! {
// We cannot skip the native trader for some specific tests, so we will have to work with
// a native trader that charges same number of units as weight
pub ParaTokensPerSecond: (XcmAssetId, u128) = (Concrete(SelfReserve::get()), 1000000000000);
// We use both the old and new anchoring logics
pub ParaTokensPerSecondOld: (XcmAssetId, u128) = (
Concrete(OldAnchoringSelfReserve::get()),
1000000000000
);
pub ParaTokensPerSecondNew: (XcmAssetId, u128) = (
Concrete(NewAnchoringSelfReserve::get()),
1000000000000
);
}

parameter_types! {
pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
pub SelfReserve: MultiLocation = MultiLocation {
// Old Self Reserve location, defines the multilocation identifiying the self-reserve currency
// This is used to match it against our Balances pallet when we receive such a MultiLocation
// (Parent, Self Para Id, Self Balances pallet index)
// This is the old anchoring way
pub OldAnchoringSelfReserve: MultiLocation = MultiLocation {
parents:1,
interior: Junctions::X2(
Parachain(MsgQueue::parachain_id().into()),
Parachain(ParachainInfo::parachain_id().into()),
PalletInstance(<Runtime as frame_system::Config>::PalletInfo::index::<Balances>().unwrap() as u8)
)
};
// Bew Self Reserve location, defines the multilocation identifiying the self-reserve currency
// This is used to match it also against our Balances pallet when we receive such
// a MultiLocation: (Self Balances pallet index)
// This is the new anchoring way
pub NewAnchoringSelfReserve: MultiLocation = MultiLocation {
parents:0,
interior: Junctions::X1(
PalletInstance(<Runtime as frame_system::Config>::PalletInfo::index::<Balances>().unwrap() as u8)
)
};

// The Locations we accept to refer to our own currency. We need to support both pre and
// post 0.9.16 versions, hence the reason for this being a Vec
pub SelfReserveRepresentations: Vec<MultiLocation> = vec![
OldAnchoringSelfReserve::get(),
NewAnchoringSelfReserve::get()
];
}
pub struct XcmConfig;
impl Config for XcmConfig {
Expand All @@ -256,7 +299,15 @@ impl Config for XcmConfig {
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
type Trader = (xcm_primitives::FirstAssetTrader<AssetType, AssetManager, XcmFeesToAccount_>,);
// We use three traders
// When we receive either representation of the self-reserve asset,
// When we receive a non-reserve asset, we use AssetManager to fetch how many
// units per second we should charge
type Trader = (
FixedRateOfFungible<ParaTokensPerSecondOld, ()>,
FixedRateOfFungible<ParaTokensPerSecondNew, ()>,
xcm_primitives::FirstAssetTrader<AssetType, AssetManager, XcmFeesToAccount_>,
);

type ResponseHandler = PolkadotXcm;
type SubscriptionService = PolkadotXcm;
Expand Down Expand Up @@ -286,7 +337,12 @@ where
fn convert(currency: CurrencyId) -> Option<MultiLocation> {
match currency {
CurrencyId::SelfReserve => {
let multi: MultiLocation = SelfReserve::get();
// For now (and until we upgrade to 0.9.16 is adapted) we need to use
// the old anchoring here
// This is not a problem in either cases, since the view of the destination
// chain does not change
// TODO! change this to NewAnchoringSelfReserve once we uprade to 0.9.16
let multi: MultiLocation = OldAnchoringSelfReserve::get();
Some(multi)
}
CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(),
Expand Down
Loading