diff --git a/Cargo.lock b/Cargo.lock index 77d62bd4d0..255068d850 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11864,7 +11864,9 @@ dependencies = [ "parity-scale-codec", "paste", "polkadot-parachain", + "polkadot-primitives", "polkadot-runtime-parachains", + "smallvec 1.6.1", "sp-core", "sp-io", "sp-runtime", diff --git a/pallets/salp/src/lib.rs b/pallets/salp/src/lib.rs index 06f233df1f..3598d83895 100644 --- a/pallets/salp/src/lib.rs +++ b/pallets/salp/src/lib.rs @@ -304,6 +304,17 @@ pub mod pallet { /// Weight information for the extrinsics in this module. type WeightInfo: WeightInfo; + + type SelfParaId: Get; + + #[pallet::constant] + type BaseXcmWeight: Get; + + #[pallet::constant] + type ContributionWeight: Get; + + #[pallet::constant] + type WithdrawWeight: Get; } #[pallet::pallet] @@ -739,7 +750,7 @@ pub mod pallet { ensure!(owner == fund.depositor, Error::::UnauthorizedAccount); - Self::xcm_ump_withdraw(index).map_err(|_| Error::::XcmFailed)?; + Self::xcm_ump_withdraw(origin, index).map_err(|_| Error::::XcmFailed)?; Self::deposit_event(Event::Withdrawing(owner, index, fund.raised)); @@ -1175,12 +1186,13 @@ pub mod pallet { T::BifrostXcmExecutor::ump_transact( MultiLocation::X1(Junction::Parachain(index)), call, + T::ContributionWeight::get(), false, ) } - fn xcm_ump_withdraw(index: ParaId) -> XcmResult { - let who: AccountIdOf = PolkadotParaId::from(index).into_account(); + fn xcm_ump_withdraw(_origin: OriginFor, index: ParaId) -> XcmResult { + let who: AccountIdOf = PolkadotParaId::from(T::SelfParaId::get()).into_account(); let withdraw = Withdraw { who, index }; let call = CrowdloanWithdrawCall::CrowdloanWithdraw(WithdrawCall::Withdraw(withdraw)) @@ -1190,6 +1202,7 @@ pub mod pallet { T::BifrostXcmExecutor::ump_transact( MultiLocation::X1(Junction::Parachain(index)), call, + T::WithdrawWeight::get(), false, ) } diff --git a/pallets/salp/src/mock.rs b/pallets/salp/src/mock.rs index 925d56f1cf..614a7472c2 100644 --- a/pallets/salp/src/mock.rs +++ b/pallets/salp/src/mock.rs @@ -171,6 +171,10 @@ parameter_types! { pub const ReleaseRatio: Percent = Percent::from_percent(50); pub const DepositTokenType: CurrencyId = CurrencyId::Token(TokenSymbol::ASG); pub const XcmTransferOrigin: TransferOriginType = TransferOriginType::FromSelf; + pub BaseXcmWeight:u64 = 1_000_000_000 as u64; + pub ContributionWeight:u64 = 1_000_000_000 as u64; + pub WithdrawWeight:u64 = 1_000_000_000 as u64; + pub const SelfParaId: u32 = 2001; } parameter_types! { @@ -198,6 +202,10 @@ impl salp::Config for Test { type VSBondValidPeriod = VSBondValidPeriod; type XcmTransferOrigin = XcmTransferOrigin; type WeightInfo = salp::TestWeightInfo; + type SelfParaId = SelfParaId; + type BaseXcmWeight = BaseXcmWeight; + type ContributionWeight = ContributionWeight; + type WithdrawWeight = WithdrawWeight; } // To control the result returned by `MockXcmExecutor` @@ -207,7 +215,16 @@ pub(crate) static mut MOCK_XCM_RESULT: (bool, bool) = (true, true); pub struct MockXcmExecutor; impl BifrostXcmExecutor for MockXcmExecutor { - fn ump_transact(_origin: MultiLocation, _call: DoubleEncoded<()>, _relayer: bool) -> XcmResult { + fn transact_weight() -> u64 { + return 0; + } + + fn ump_transact( + _origin: MultiLocation, + _call: DoubleEncoded<()>, + _weight: u64, + _relayer: bool, + ) -> XcmResult { let result = unsafe { MOCK_XCM_RESULT.0 }; match result { diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 08ecc1fa4c..20651b9be5 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -170,6 +170,7 @@ parameter_types! { pub const NativeCurrencyId: CurrencyId = CurrencyId::Native(TokenSymbol::ASG); pub const RelayCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); pub const StableCurrencyId: CurrencyId = CurrencyId::Stable(TokenSymbol::AUSD); + pub SelfParaId: u32 = ParachainInfo::parachain_id().into(); } impl frame_system::Config for Runtime { @@ -955,6 +956,8 @@ parameter_types! { pub const SlotLength: BlockNumber = 8u32 as BlockNumber; pub const XcmTransferOrigin: TransferOriginType = TransferOriginType::FromRelayChain; pub XcmWeight: XcmBaseWeight = XCM_WEIGHT.into(); + pub ContributionWeight:u64 = XCM_WEIGHT.into(); + pub WithdrawWeight:u64 = XCM_WEIGHT.into(); } impl bifrost_salp::Config for Runtime { @@ -975,7 +978,11 @@ impl bifrost_salp::Config for Runtime { type SubmissionDeposit = SubmissionDeposit; type VSBondValidPeriod = VSBondValidPeriod; type XcmTransferOrigin = XcmTransferOrigin; - type WeightInfo = weights::bifrost_salp::WeightInfo; // bifrost_salp::TestWeightInfo; + type WeightInfo = weights::bifrost_salp::WeightInfo; + type SelfParaId = SelfParaId; + type ContributionWeight = ContributionWeight; + type WithdrawWeight = WithdrawWeight; + type BaseXcmWeight = XcmWeight; } parameter_types! { @@ -1010,7 +1017,6 @@ impl bifrost_vsbond_auction::Config for Runtime { // zenlink runtime start parameter_types! { pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink"); - pub SelfParaId: u32 = ParachainInfo::parachain_id().into(); pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3% // xcm diff --git a/runtime/dev/src/lib.rs b/runtime/dev/src/lib.rs index 7a46cbb884..cfa88f7513 100644 --- a/runtime/dev/src/lib.rs +++ b/runtime/dev/src/lib.rs @@ -926,6 +926,8 @@ parameter_types! { pub const SlotLength: BlockNumber = 8u32 as BlockNumber; pub const XcmTransferOrigin: TransferOriginType = TransferOriginType::FromRelayChain; pub XcmWeight: XcmBaseWeight = XCM_WEIGHT.into(); + pub ContributionWeight:u64 = XCM_WEIGHT.into(); + pub WithdrawWeight:u64 = XCM_WEIGHT.into(); } impl bifrost_salp::Config for Runtime { @@ -946,7 +948,11 @@ impl bifrost_salp::Config for Runtime { type SubmissionDeposit = SubmissionDeposit; type VSBondValidPeriod = VSBondValidPeriod; type XcmTransferOrigin = XcmTransferOrigin; - type WeightInfo = weights::bifrost_salp::WeightInfo; // bifrost_salp::TestWeightInfo; + type WeightInfo = weights::bifrost_salp::WeightInfo; + type SelfParaId = SelfParaId; + type ContributionWeight = ContributionWeight; + type WithdrawWeight = WithdrawWeight; + type BaseXcmWeight = XcmWeight; } parameter_types! { diff --git a/xcm-support/Cargo.toml b/xcm-support/Cargo.toml index f4ec09bc62..1cc1fde795 100644 --- a/xcm-support/Cargo.toml +++ b/xcm-support/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } paste = "1.0.5" +smallvec = "1.6.1" sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false } @@ -31,6 +32,7 @@ parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polk pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } [features] default = ["std"] diff --git a/xcm-support/src/lib.rs b/xcm-support/src/lib.rs index 8d21911151..f9cbc48600 100644 --- a/xcm-support/src/lib.rs +++ b/xcm-support/src/lib.rs @@ -156,11 +156,32 @@ pub struct BifrostXcmAdaptor(PhantomData<(XcmSender, B impl> BifrostXcmExecutor for BifrostXcmAdaptor { - fn ump_transact(origin: MultiLocation, call: DoubleEncoded<()>, relay: bool) -> XcmResult { - let mut message = Xcm::Transact { - origin_type: OriginKind::SovereignAccount, - require_weight_at_most: u64::MAX, - call, + fn transact_weight() -> u64 { + return 4 * BaseXcmWeight::get(); + } + + fn ump_transact( + origin: MultiLocation, + call: DoubleEncoded<()>, + weight: u64, + relay: bool, + ) -> XcmResult { + let mut message = Xcm::WithdrawAsset { + assets: vec![MultiAsset::ConcreteFungible { + id: MultiLocation::Null, + amount: (weight + Self::transact_weight()) as u128, + }], + effects: vec![Order::BuyExecution { + fees: MultiAsset::All, + weight: weight + 2 * BaseXcmWeight::get(), + debt: 2 * BaseXcmWeight::get(), + halt_on_error: true, + xcm: vec![Xcm::Transact { + origin_type: OriginKind::SovereignAccount, + require_weight_at_most: u64::MAX, + call, + }], + }], }; if relay { diff --git a/xcm-support/src/mock.rs b/xcm-support/src/mock.rs index f1b22696f1..a5fe952097 100644 --- a/xcm-support/src/mock.rs +++ b/xcm-support/src/mock.rs @@ -500,17 +500,24 @@ pub mod para { pub mod relay { use cumulus_primitives_core::ParaId; - use frame_support::{construct_runtime, parameter_types, traits::All, weights::Weight}; + use frame_support::{ + construct_runtime, parameter_types, + traits::{All, OnUnbalanced}, + weights::{Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial}, + }; + use pallet_balances::NegativeImbalance; + use polkadot_primitives; use polkadot_runtime_parachains::{configuration, origin, shared, ump}; + use smallvec::smallvec; use sp_core::H256; - use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32}; + use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32, Perbill}; use xcm::v0::{MultiAsset, MultiLocation, NetworkId}; use xcm_builder::{ - AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative, + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, - CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfConcreteFungible, FixedWeightBounds, - IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, + CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsConcrete, LocationInverter, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, + TakeWeightCredit, UsingComponents, }; use xcm_executor::{Config, XcmExecutor}; @@ -521,6 +528,33 @@ pub mod relay { pub const BlockHashCount: u64 = 250; } + /// Logic for the author to get a portion of fees. + pub struct ToAuthor(sp_std::marker::PhantomData); + impl OnUnbalanced> for ToAuthor + where + R: pallet_balances::Config, + ::AccountId: From, + ::AccountId: Into, + ::Event: From>, + { + fn on_nonzero_unbalanced(_amount: NegativeImbalance) {} + } + + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + let p = 1_000_000_00; + let q = 1_000_000; + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } + impl frame_system::Config for Runtime { type AccountData = pallet_balances::AccountData; type AccountId = AccountId; @@ -598,7 +632,7 @@ pub mod relay { } pub type XcmRouter = crate::mock::RelayChainXcmRouter; - pub type Barrier = AllowUnpaidExecutionFrom>; + pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecutionFrom>); pub struct XcmConfig; impl Config for XcmConfig { @@ -610,7 +644,8 @@ pub mod relay { type LocationInverter = LocationInverter; type OriginConverter = LocalOriginConverter; type ResponseHandler = (); - type Trader = FixedRateOfConcreteFungible; + type Trader = + UsingComponents>; type Weigher = FixedWeightBounds; type XcmSender = XcmRouter; } diff --git a/xcm-support/src/tests.rs b/xcm-support/src/tests.rs index bb329fc986..017129a38f 100644 --- a/xcm-support/src/tests.rs +++ b/xcm-support/src/tests.rs @@ -21,10 +21,13 @@ mod tests { use codec::Encode; use frame_support::assert_ok; use xcm::v0::{ - Junction::{self, Parachain, Parent}, + Junction, + Junction::{Parachain, Parent}, + MultiAsset, MultiAsset::*, + MultiLocation, MultiLocation::*, - NetworkId, OriginKind, + NetworkId, OriginKind, Xcm, Xcm::*, }; @@ -112,6 +115,43 @@ mod tests { }); } + #[test] + fn ump_transact_buy_weight() { + MockNet::reset(); + + let remark = + relay::Call::System(frame_system::Call::::remark_with_event(vec![ + 1, 2, 3, + ])); + ParaA::execute_with(|| { + assert_ok!(ParachainPalletXcm::send_xcm( + Null, + X1(Parent), + Xcm::WithdrawAsset { + assets: vec![MultiAsset::ConcreteFungible { + id: MultiLocation::Null, + amount: 0 + }], + effects: vec![Order::BuyExecution { + fees: MultiAsset::All, + weight: INITIAL_BALANCE as u64, + debt: INITIAL_BALANCE as u64, + halt_on_error: false, + xcm: vec![Xcm::Transact { + origin_type: OriginKind::SovereignAccount, + require_weight_at_most: u64::MAX, + call: remark.encode().into(), + }], + }], + } + )); + }); + + Relay::execute_with(|| { + print_events::("RelayChain"); + }); + } + #[test] fn xcmp() { MockNet::reset(); diff --git a/xcm-support/src/traits.rs b/xcm-support/src/traits.rs index 798c8b3079..130a8bb316 100644 --- a/xcm-support/src/traits.rs +++ b/xcm-support/src/traits.rs @@ -43,7 +43,14 @@ pub trait HandleXcmpMessage { /// Bifrost Xcm Executor pub trait BifrostXcmExecutor { - fn ump_transact(origin: MultiLocation, call: DoubleEncoded<()>, relay: bool) -> XcmResult; + fn transact_weight() -> u64; + + fn ump_transact( + origin: MultiLocation, + call: DoubleEncoded<()>, + weight: u64, + relay: bool, + ) -> XcmResult; fn ump_transfer_asset( origin: MultiLocation,