Skip to content

Commit

Permalink
Adjust XCM trader (#143)
Browse files Browse the repository at this point in the history
* init LocalAssetTrader

* LocalAssetTrader

* Update trader for pangolin & crab

* format

* Update comments

* Update logs

* format

* Format

* Simplify code

Co-authored-by: fisher <denny.wang@itering.io>
Co-authored-by: Xavier Lau <xavier@inv.cafe>
  • Loading branch information
3 people committed Jan 4, 2023
1 parent 431c1b1 commit 015eed1
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 22 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ account = { default-features = false, git = "https://github.com/darwinia-network

# polkadot
xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.30" }
xcm-builder = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.30" }
xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.30" }

# substrate
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
pallet-collective = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
pallet-collective = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }

[features]
default = ["std"]
Expand All @@ -47,12 +49,14 @@ std = [

# polkadot
"xcm/std",
"xcm-builder/std",
"xcm-executor/std",

# substrate
"frame-support/std",
"frame-system/std",
"pallet-collective/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
94 changes: 86 additions & 8 deletions runtime/common/src/xcm_configs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,23 @@ use codec::Encode;
// darwinia
use dc_primitives::GWEI;
// polkadot
use xcm::latest::{prelude::*, Weight as XCMWeight};
use xcm_executor::traits::{Convert, ShouldExecute};
use xcm::latest::{prelude::*, Weight as XcmWeight};
use xcm_builder::TakeRevenue;
use xcm_executor::{
traits::{Convert, ShouldExecute, WeightTrader},
Assets,
};
// substrate
use frame_support::{log, traits::ConstU128};
use frame_support::{
log,
traits::{
tokens::currency::Currency as CurrencyT, ConstU128, Get, OnUnbalanced as OnUnbalancedT,
},
weights::{Weight, WeightToFee as WeightToFeeT},
};
use sp_io::hashing::blake2_256;
use sp_std::borrow::Borrow;
use sp_runtime::traits::{SaturatedConversion, Saturating, Zero};
use sp_std::{borrow::Borrow, result::Result};

/// Base balance required for the XCM unit weight.
pub type XcmBaseWeightFee = ConstU128<GWEI>;
Expand Down Expand Up @@ -60,8 +71,8 @@ where
fn should_execute<RuntimeCall>(
origin: &MultiLocation,
message: &mut Xcm<RuntimeCall>,
max_weight: XCMWeight,
weight_credit: &mut XCMWeight,
max_weight: XcmWeight,
weight_credit: &mut XcmWeight,
) -> Result<(), ()> {
Deny::should_execute(origin, message, max_weight, weight_credit)?;
Allow::should_execute(origin, message, max_weight, weight_credit)
Expand All @@ -75,8 +86,8 @@ impl ShouldExecute for DenyReserveTransferToRelayChain {
origin: &MultiLocation,

message: &mut Xcm<RuntimeCall>,
_max_weight: XCMWeight,
_weight_credit: &mut XCMWeight,
_max_weight: XcmWeight,
_weight_credit: &mut XcmWeight,
) -> Result<(), ()> {
if message.0.iter().any(|inst| {
matches!(
Expand Down Expand Up @@ -126,3 +137,70 @@ impl<AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> Convert<MultiLocation,
Err(())
}
}

/// Weight trader to set the right price for weight and then places any weight bought into the right
/// account. Refer to: https://github.com/paritytech/polkadot/blob/release-v0.9.30/xcm/xcm-builder/src/weight.rs#L242-L305
pub struct LocalAssetTrader<
WeightToFee: WeightToFeeT<Balance = Currency::Balance>,
AssetId: Get<MultiLocation>,
AccountId,
Currency: CurrencyT<AccountId>,
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
R: TakeRevenue,
>(
XcmWeight,
Currency::Balance,
PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced, R)>,
);
impl<
WeightToFee: WeightToFeeT<Balance = Currency::Balance>,
AssetId: Get<MultiLocation>,
AccountId,
Currency: CurrencyT<AccountId>,
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
R: TakeRevenue,
> WeightTrader for LocalAssetTrader<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced, R>
{
fn new() -> Self {
Self(0, Zero::zero(), PhantomData)
}

fn buy_weight(&mut self, weight: XcmWeight, payment: Assets) -> Result<Assets, XcmError> {
log::trace!(target: "xcm::weight", "LocalAssetTrader::buy_weight weight: {:?}, payment: {:?}", weight, payment);
let amount = WeightToFee::weight_to_fee(&Weight::from_ref_time(weight));
let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
let required: MultiAsset = (Concrete(AssetId::get()), u128_amount).into();
let unused = payment.checked_sub(required.clone()).map_err(|_| XcmError::TooExpensive)?;
self.0 = self.0.saturating_add(weight);
self.1 = self.1.saturating_add(amount);
R::take_revenue(required);
Ok(unused)
}

fn refund_weight(&mut self, weight: XcmWeight) -> Option<MultiAsset> {
log::trace!(target: "xcm::weight", "LocalAssetTrader::refund_weight weight: {:?}", weight);
let weight = weight.min(self.0);
let amount = WeightToFee::weight_to_fee(&Weight::from_ref_time(weight));
self.0 -= weight;
self.1 = self.1.saturating_sub(amount);
let amount: u128 = amount.saturated_into();
if amount > 0 {
Some((AssetId::get(), amount).into())
} else {
None
}
}
}
impl<
WeightToFee: WeightToFeeT<Balance = Currency::Balance>,
AssetId: Get<MultiLocation>,
AccountId,
Currency: CurrencyT<AccountId>,
OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
R: TakeRevenue,
> Drop for LocalAssetTrader<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced, R>
{
fn drop(&mut self) {
OnUnbalanced::on_unbalanced(Currency::issue(self.1));
}
}
26 changes: 23 additions & 3 deletions runtime/crab/src/pallets/polkadot_xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

// darwinia
use crate::*;
// substrate
use frame_support::traits::Currency;

/// Means for transacting assets on this chain.
pub type LocalAssetTransactor = xcm_builder::CurrencyAdapter<
Expand Down Expand Up @@ -98,6 +100,25 @@ frame_support::parameter_types! {
pub UnitWeightCost: u64 = 1_000_000_000;
}

pub struct ToTreasury;
impl xcm_builder::TakeRevenue for ToTreasury {
fn take_revenue(revenue: xcm::latest::prelude::MultiAsset) {
if let xcm::latest::prelude::MultiAsset {
id: xcm::latest::prelude::Concrete(_location),
fun: xcm::latest::prelude::Fungible(amount),
} = revenue
{
let treasury_account = Treasury::account_id();
let _ = Balances::deposit_creating(&treasury_account, amount);

frame_support::log::trace!(
target: "xcm::weight",
"LocalAssetTrader::to_treasury amount: {amount:?}, treasury: {treasury_account:?}"
);
}
}
}

pub struct XcmExecutorConfig;
impl xcm_executor::Config for XcmExecutorConfig {
type AssetClaims = PolkadotXcm;
Expand All @@ -113,12 +134,13 @@ impl xcm_executor::Config for XcmExecutorConfig {
type ResponseHandler = PolkadotXcm;
type RuntimeCall = RuntimeCall;
type SubscriptionService = PolkadotXcm;
type Trader = xcm_builder::UsingComponents<
type Trader = xcm_configs::LocalAssetTrader<
ConstantMultiplier<Balance, darwinia_common_runtime::xcm_configs::XcmBaseWeightFee>,
AnchoringSelfReserve,
AccountId,
Balances,
DealWithFees<Runtime>,
ToTreasury,
>;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmSender = XcmRouter;
Expand Down Expand Up @@ -147,8 +169,6 @@ impl pallet_xcm::Config for Runtime {
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmExecuteFilter = frame_support::traits::Everything;
// ^ Disable dispatchable execute on the XCM pallet.
// Needs to be `Everything` for local testing.
type XcmExecutor = xcm_executor::XcmExecutor<XcmExecutorConfig>;
type XcmReserveTransferFilter = frame_support::traits::Everything;
type XcmRouter = XcmRouter;
Expand Down
26 changes: 23 additions & 3 deletions runtime/darwinia/src/pallets/polkadot_xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

// darwinia
use crate::*;
// substrate
use frame_support::traits::Currency;

/// Means for transacting assets on this chain.
pub type LocalAssetTransactor = xcm_builder::CurrencyAdapter<
Expand Down Expand Up @@ -98,6 +100,25 @@ frame_support::parameter_types! {
pub UnitWeightCost: u64 = 1_000_000_000;
}

pub struct ToTreasury;
impl xcm_builder::TakeRevenue for ToTreasury {
fn take_revenue(revenue: xcm::latest::prelude::MultiAsset) {
if let xcm::latest::prelude::MultiAsset {
id: xcm::latest::prelude::Concrete(_location),
fun: xcm::latest::prelude::Fungible(amount),
} = revenue
{
let treasury_account = Treasury::account_id();
let _ = Balances::deposit_creating(&treasury_account, amount);

frame_support::log::trace!(
target: "xcm::weight",
"LocalAssetTrader::to_treasury amount: {amount:?}, treasury: {treasury_account:?}"
);
}
}
}

pub struct XcmExecutorConfig;
impl xcm_executor::Config for XcmExecutorConfig {
type AssetClaims = PolkadotXcm;
Expand All @@ -113,12 +134,13 @@ impl xcm_executor::Config for XcmExecutorConfig {
type ResponseHandler = PolkadotXcm;
type RuntimeCall = RuntimeCall;
type SubscriptionService = PolkadotXcm;
type Trader = xcm_builder::UsingComponents<
type Trader = xcm_configs::LocalAssetTrader<
ConstantMultiplier<Balance, darwinia_common_runtime::xcm_configs::XcmBaseWeightFee>,
AnchoringSelfReserve,
AccountId,
Balances,
DealWithFees<Runtime>,
ToTreasury,
>;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmSender = XcmRouter;
Expand Down Expand Up @@ -147,8 +169,6 @@ impl pallet_xcm::Config for Runtime {
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmExecuteFilter = frame_support::traits::Everything;
// ^ Disable dispatchable execute on the XCM pallet.
// Needs to be `Everything` for local testing.
type XcmExecutor = xcm_executor::XcmExecutor<XcmExecutorConfig>;
type XcmReserveTransferFilter = frame_support::traits::Everything;
type XcmRouter = XcmRouter;
Expand Down
1 change: 1 addition & 0 deletions runtime/pangolin/src/pallets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ mod elections_phragmen;
mod membership;

mod treasury;
pub use treasury::*;

mod tips;

Expand Down
26 changes: 23 additions & 3 deletions runtime/pangolin/src/pallets/polkadot_xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

// darwinia
use crate::*;
// substrate
use frame_support::traits::Currency;

/// Means for transacting assets on this chain.
pub type LocalAssetTransactor = xcm_builder::CurrencyAdapter<
Expand Down Expand Up @@ -98,6 +100,25 @@ frame_support::parameter_types! {
pub UnitWeightCost: u64 = 1_000_000_000;
}

pub struct ToTreasury;
impl xcm_builder::TakeRevenue for ToTreasury {
fn take_revenue(revenue: xcm::latest::prelude::MultiAsset) {
if let xcm::latest::prelude::MultiAsset {
id: xcm::latest::prelude::Concrete(_location),
fun: xcm::latest::prelude::Fungible(amount),
} = revenue
{
let treasury_account = Treasury::account_id();
let _ = Balances::deposit_creating(&treasury_account, amount);

frame_support::log::trace!(
target: "xcm::weight",
"LocalAssetTrader::to_treasury amount: {amount:?}, treasury: {treasury_account:?}"
);
}
}
}

pub struct XcmExecutorConfig;
impl xcm_executor::Config for XcmExecutorConfig {
type AssetClaims = PolkadotXcm;
Expand All @@ -113,12 +134,13 @@ impl xcm_executor::Config for XcmExecutorConfig {
type ResponseHandler = PolkadotXcm;
type RuntimeCall = RuntimeCall;
type SubscriptionService = PolkadotXcm;
type Trader = xcm_builder::UsingComponents<
type Trader = xcm_configs::LocalAssetTrader<
ConstantMultiplier<Balance, darwinia_common_runtime::xcm_configs::XcmBaseWeightFee>,
AnchoringSelfReserve,
AccountId,
Balances,
DealWithFees<Runtime>,
ToTreasury,
>;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmSender = XcmRouter;
Expand Down Expand Up @@ -147,8 +169,6 @@ impl pallet_xcm::Config for Runtime {
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmExecuteFilter = frame_support::traits::Everything;
// ^ Disable dispatchable execute on the XCM pallet.
// Needs to be `Everything` for local testing.
type XcmExecutor = xcm_executor::XcmExecutor<XcmExecutorConfig>;
type XcmReserveTransferFilter = frame_support::traits::Everything;
type XcmRouter = XcmRouter;
Expand Down

0 comments on commit 015eed1

Please sign in to comment.