Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
58 changes: 29 additions & 29 deletions Cargo.dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,34 @@ scale-info = { version = "2.10.0", default-features = false, features = ["derive
serde = { version = "1.0.189" }
parity-scale-codec = { version = "3.6.5", default-features = false, features = ["max-encoded-len"] }

cumulus-pallet-xcm = { version = "0.7.0", default-features = false }
cumulus-primitives-core = { version = "0.7.0", default-features = false }
frame-benchmarking = { version = "28.0.0", default-features = false }
frame-support = { version = "28.0.0", default-features = false }
frame-system = { version = "28.0.0", default-features = false }
pallet-balances = { version = "28.0.0", default-features = false }
pallet-elections-phragmen = { version = "29.0.0", default-features = false }
pallet-message-queue = { version = "31.0.0", default-features = false }
pallet-preimage = { version = "28.0.0", default-features = false }
pallet-root-testing = { version = "4.0.0", default-features = false }
pallet-scheduler = { version = "29.0.0", default-features = false }
pallet-treasury = { version = "27.0.0", default-features = false }
pallet-xcm = { version = "7.0.0", default-features = false }
polkadot-parachain-primitives = { version = "6.0.0", default-features = false }
polkadot-runtime-common = { version = "7.0.0", default-features = false }
polkadot-runtime-parachains = { version = "7.0.0", default-features = false }
sp-api = { version = "26.0.0", default-features = false }
sp-application-crypto = { version = "30.0.0", default-features = false }
sp-arithmetic = { version = "23.0.0", default-features = false }
sp-core = { version = "28.0.0", default-features = false }
sp-io = { version = "30.0.0", default-features = false }
sp-runtime = { version = "31.0.1", default-features = false }
sp-runtime-interface = { version = "24.0.0", default-features = false }
sp-staking = { version = "26.0.0", default-features = false }
cumulus-pallet-xcm = { version = "0.8.0", default-features = false }
cumulus-primitives-core = { version = "0.8.0", default-features = false }
frame-benchmarking = { version = "29.0.0", default-features = false }
frame-support = { version = "29.0.0", default-features = false }
frame-system = { version = "29.0.0", default-features = false }
pallet-balances = { version = "29.0.0", default-features = false }
pallet-elections-phragmen = { version = "30.0.0", default-features = false }
pallet-message-queue = { version = "32.0.0", default-features = false }
pallet-preimage = { version = "29.0.0", default-features = false }
pallet-root-testing = { version = "5.0.0", default-features = false }
pallet-scheduler = { version = "30.0.0", default-features = false }
pallet-treasury = { version = "28.0.0", default-features = false }
pallet-xcm = { version = "8.0.0", default-features = false }
polkadot-parachain-primitives = { version = "7.0.0", default-features = false }
polkadot-runtime-common = { version = "8.0.0", default-features = false }
polkadot-runtime-parachains = { version = "8.0.0", default-features = false }
sp-api = { version = "27.0.0", default-features = false }
sp-application-crypto = { version = "31.0.0", default-features = false }
sp-arithmetic = { version = "24.0.0", default-features = false }
sp-core = { version = "29.0.0", default-features = false }
sp-io = { version = "31.0.0", default-features = false }
sp-runtime = { version = "32.0.0", default-features = false }
sp-runtime-interface = { version = "25.0.0", default-features = false }
sp-staking = { version = "27.0.0", default-features = false }
sp-std = { version = "14.0.0", default-features = false }
sp-storage = { version = "19.0.0", default-features = false }
xcm = { package = "staging-xcm", version = "7.0.0", default-features = false }
xcm-builder = { package = "staging-xcm-builder", version = "7.0.0", default-features = false }
xcm-executor = { package = "staging-xcm-executor", version = "7.0.0", default-features = false }
sp-storage = { version = "20.0.0", default-features = false }
xcm = { package = "staging-xcm", version = "8.0.0", default-features = false }
xcm-builder = { package = "staging-xcm-builder", version = "8.0.0", default-features = false }
xcm-executor = { package = "staging-xcm-executor", version = "8.0.0", default-features = false }

xcm-simulator = { version = "7.0.0" }
xcm-simulator = { version = "8.0.0" }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The Open Runtime Module Library (ORML) is a community maintained collection of S

#### Tokens
- [asset-registry](https://github.com/open-web3-stack/open-runtime-module-library/tree/master/asset-registry)
- Register asset / token metadata including name, decimals, and XCM MultiLocation
- Register asset / token metadata including name, decimals, and XCM Location
- Partially based on the Acala’s asset-registry pallet, which includes some Acala specific code (e.g. EVM+) so not suitable for other teams.
- [currencies](https://github.com/open-web3-stack/open-runtime-module-library/tree/master/currencies)
- Provide an unified interface to combine pallet-balances and orml-tokens
Expand Down
91 changes: 49 additions & 42 deletions asset-registry/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ use sp_runtime::{
ArithmeticError, FixedU128,
};
use sp_std::prelude::*;
use xcm::v3::{prelude::*, Weight as XcmWeight};
use xcm::VersionedMultiLocation;
use xcm::VersionedLocation;
use xcm::{
v3,
v4::{prelude::*, Weight as XcmWeight},
};
use xcm_builder::TakeRevenue;
use xcm_executor::{traits::WeightTrader, Assets};
use xcm_executor::{traits::WeightTrader, AssetsInHolding};

/// Alias for AssetMetadata to improve readability (and to placate clippy)
pub type DefaultAssetMetadata<T> =
Expand Down Expand Up @@ -54,7 +57,7 @@ where
/// conversion rate.
pub struct FixedRateAssetRegistryTrader<P: FixedConversionRateProvider>(PhantomData<P>);
impl<P: FixedConversionRateProvider> WeightToFeeConverter for FixedRateAssetRegistryTrader<P> {
fn convert_weight_to_fee(location: &MultiLocation, weight: Weight) -> Option<u128> {
fn convert_weight_to_fee(location: &Location, weight: Weight) -> Option<u128> {
let fee_per_second = P::get_fee_per_second(location)?;
let weight_ratio = FixedU128::saturating_from_rational(weight.ref_time(), WEIGHT_REF_TIME_PER_SECOND);
let amount = weight_ratio.saturating_mul_int(fee_per_second);
Expand All @@ -66,7 +69,7 @@ impl<P: FixedConversionRateProvider> WeightToFeeConverter for FixedRateAssetRegi
/// bought weight.
pub struct BoughtWeight {
weight: Weight,
asset_location: MultiLocation,
asset_location: Location,
amount: u128,
}

Expand All @@ -90,49 +93,53 @@ impl<W: WeightToFeeConverter, R: TakeRevenue> WeightTrader for AssetRegistryTrad
}
}

fn buy_weight(&mut self, weight: XcmWeight, payment: Assets, _context: &XcmContext) -> Result<Assets, XcmError> {
fn buy_weight(
&mut self,
weight: XcmWeight,
payment: AssetsInHolding,
_context: &XcmContext,
) -> Result<AssetsInHolding, XcmError> {
log::trace!(
target: "xcm::weight",
"AssetRegistryTrader::buy_weight weight: {:?}, payment: {:?}",
weight, payment,
);

for (asset, _) in payment.fungible.iter() {
if let AssetId::Concrete(ref location) = asset {
if matches!(self.bought_weight, Some(ref bought) if &bought.asset_location != location) {
// we already bought another asset - don't attempt to buy this one since
// we won't be able to refund it
continue;
let AssetId(ref location) = asset;
if matches!(self.bought_weight, Some(ref bought) if &bought.asset_location != location) {
// we already bought another asset - don't attempt to buy this one since
// we won't be able to refund it
continue;
}

if let Some(fee_increase) = W::convert_weight_to_fee(location, weight) {
if fee_increase == 0 {
// if the fee is set very low it could lead to zero fees, in which case
// constructing the fee asset item to subtract from payment would fail.
// Therefore, provide early exit
return Ok(payment);
}

if let Some(fee_increase) = W::convert_weight_to_fee(location, weight) {
if fee_increase == 0 {
// if the fee is set very low it could lead to zero fees, in which case
// constructing the fee asset item to subtract from payment would fail.
// Therefore, provide early exit
return Ok(payment);
}

if let Ok(unused) = payment.clone().checked_sub((*asset, fee_increase).into()) {
let (existing_weight, existing_fee) = match self.bought_weight {
Some(ref x) => (x.weight, x.amount),
None => (Weight::zero(), 0),
};

self.bought_weight = Some(BoughtWeight {
amount: existing_fee.checked_add(fee_increase).ok_or(XcmError::Overflow)?,
weight: existing_weight.checked_add(&weight).ok_or(XcmError::Overflow)?,
asset_location: *location,
});
return Ok(unused);
}
if let Ok(unused) = payment.clone().checked_sub((asset.clone(), fee_increase).into()) {
let (existing_weight, existing_fee) = match self.bought_weight {
Some(ref x) => (x.weight, x.amount),
None => (Weight::zero(), 0),
};

self.bought_weight = Some(BoughtWeight {
amount: existing_fee.checked_add(fee_increase).ok_or(XcmError::Overflow)?,
weight: existing_weight.checked_add(&weight).ok_or(XcmError::Overflow)?,
asset_location: location.clone(),
});
return Ok(unused);
}
}
}
Err(XcmError::TooExpensive)
}

fn refund_weight(&mut self, weight: XcmWeight, _context: &XcmContext) -> Option<MultiAsset> {
fn refund_weight(&mut self, weight: XcmWeight, _context: &XcmContext) -> Option<Asset> {
log::trace!(target: "xcm::weight", "AssetRegistryTrader::refund_weight weight: {:?}", weight);

match self.bought_weight {
Expand All @@ -144,7 +151,7 @@ impl<W: WeightToFeeConverter, R: TakeRevenue> WeightTrader for AssetRegistryTrad
bought.weight = new_weight;
bought.amount = new_amount;

Some((AssetId::Concrete(bought.asset_location), refunded_amount).into())
Some((AssetId(bought.asset_location.clone()), refunded_amount).into())
}
None => None, // nothing to refund
}
Expand All @@ -154,7 +161,7 @@ impl<W: WeightToFeeConverter, R: TakeRevenue> WeightTrader for AssetRegistryTrad
impl<W: WeightToFeeConverter, R: TakeRevenue> Drop for AssetRegistryTrader<W, R> {
fn drop(&mut self) {
if let Some(ref bought) = self.bought_weight {
R::take_revenue((AssetId::Concrete(bought.asset_location), bought.amount).into());
R::take_revenue((AssetId(bought.asset_location.clone()), bought.amount).into());
}
}
}
Expand All @@ -180,22 +187,22 @@ impl<T: Config> Inspect for Pallet<T> {
type CustomMetadata = T::CustomMetadata;
type StringLimit = T::StringLimit;

fn asset_id(location: &MultiLocation) -> Option<Self::AssetId> {
Pallet::<T>::location_to_asset_id(location)
fn asset_id(location: &Location) -> Option<Self::AssetId> {
Pallet::<T>::location_to_asset_id(v3::Location::try_from(location.clone()).ok()?)
}

fn metadata(id: &Self::AssetId) -> Option<AssetMetadata<Self::Balance, Self::CustomMetadata, Self::StringLimit>> {
Pallet::<T>::metadata(id)
}

fn metadata_by_location(
location: &MultiLocation,
location: &Location,
) -> Option<AssetMetadata<Self::Balance, Self::CustomMetadata, Self::StringLimit>> {
Pallet::<T>::fetch_metadata_by_location(location)
Pallet::<T>::fetch_metadata_by_location(&v3::Location::try_from(location.clone()).ok()?)
}

fn location(asset_id: &Self::AssetId) -> Result<Option<MultiLocation>, DispatchError> {
Pallet::<T>::multilocation(asset_id)
fn location(asset_id: &Self::AssetId) -> Result<Option<Location>, DispatchError> {
Pallet::<T>::location(asset_id).map(|l| l.and_then(|l| l.try_into().ok()))
}
}

Expand All @@ -213,7 +220,7 @@ impl<T: Config> Mutate for Pallet<T> {
name: Option<BoundedVec<u8, Self::StringLimit>>,
symbol: Option<BoundedVec<u8, Self::StringLimit>>,
existential_deposit: Option<Self::Balance>,
location: Option<Option<VersionedMultiLocation>>,
location: Option<Option<VersionedLocation>>,
additional: Option<Self::CustomMetadata>,
) -> DispatchResult {
Pallet::<T>::do_update_asset(
Expand Down
28 changes: 14 additions & 14 deletions asset-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ use sp_runtime::{
DispatchResult,
};
use sp_std::prelude::*;
use xcm::{v3::prelude::*, VersionedMultiLocation};
use xcm::{v3::prelude::*, VersionedLocation};

pub use impls::*;
pub use module::*;
use module::*;
pub use weights::WeightInfo;

mod impls;
Expand Down Expand Up @@ -67,7 +67,7 @@ pub mod module {
pub enum Error<T> {
/// Asset was not found.
AssetNotFound,
/// The version of the `VersionedMultiLocation` value used is not able
/// The version of the `VersionedLocation` value used is not able
/// to be interpreted.
BadVersion,
/// The asset id is invalid.
Expand Down Expand Up @@ -104,11 +104,11 @@ pub mod module {
OptionQuery,
>;

/// Maps a multilocation to an asset id - useful when processing xcm
/// Maps a location to an asset id - useful when processing xcm
/// messages.
#[pallet::storage]
#[pallet::getter(fn location_to_asset_id)]
pub type LocationToAssetId<T: Config> = StorageMap<_, Twox64Concat, MultiLocation, T::AssetId, OptionQuery>;
pub type LocationToAssetId<T: Config> = StorageMap<_, Twox64Concat, Location, T::AssetId, OptionQuery>;

/// The last processed asset id - used when assigning a sequential id.
#[pallet::storage]
Expand Down Expand Up @@ -172,7 +172,7 @@ pub mod module {
name: Option<BoundedVec<u8, T::StringLimit>>,
symbol: Option<BoundedVec<u8, T::StringLimit>>,
existential_deposit: Option<T::Balance>,
location: Option<Option<VersionedMultiLocation>>,
location: Option<Option<VersionedLocation>>,
additional: Option<T::CustomMetadata>,
) -> DispatchResult {
T::AuthorityOrigin::ensure_origin(origin, &Some(asset_id.clone()))?;
Expand Down Expand Up @@ -239,7 +239,7 @@ impl<T: Config> Pallet<T> {
name: Option<BoundedVec<u8, T::StringLimit>>,
symbol: Option<BoundedVec<u8, T::StringLimit>>,
existential_deposit: Option<T::Balance>,
location: Option<Option<VersionedMultiLocation>>,
location: Option<Option<VersionedLocation>>,
additional: Option<T::CustomMetadata>,
) -> DispatchResult {
Metadata::<T>::try_mutate(&asset_id, |maybe_metadata| -> DispatchResult {
Expand Down Expand Up @@ -281,13 +281,13 @@ impl<T: Config> Pallet<T> {
}

pub fn fetch_metadata_by_location(
location: &MultiLocation,
location: &Location,
) -> Option<AssetMetadata<T::Balance, T::CustomMetadata, T::StringLimit>> {
let asset_id = LocationToAssetId::<T>::get(location)?;
Metadata::<T>::get(asset_id)
}

pub fn multilocation(asset_id: &T::AssetId) -> Result<Option<MultiLocation>, DispatchError> {
pub fn location(asset_id: &T::AssetId) -> Result<Option<Location>, DispatchError> {
Metadata::<T>::get(asset_id)
.and_then(|metadata| {
metadata
Expand All @@ -300,14 +300,14 @@ impl<T: Config> Pallet<T> {
/// update LocationToAssetId mapping if the location changed
fn do_update_location(
asset_id: T::AssetId,
old_location: Option<VersionedMultiLocation>,
new_location: Option<VersionedMultiLocation>,
old_location: Option<VersionedLocation>,
new_location: Option<VersionedLocation>,
) -> DispatchResult {
// Update `LocationToAssetId` only if location changed
if new_location != old_location {
// remove the old location lookup if it exists
if let Some(ref old_location) = old_location {
let location: MultiLocation = old_location.clone().try_into().map_err(|()| Error::<T>::BadVersion)?;
let location: Location = old_location.clone().try_into().map_err(|()| Error::<T>::BadVersion)?;
LocationToAssetId::<T>::remove(location);
}

Expand All @@ -321,9 +321,9 @@ impl<T: Config> Pallet<T> {
}

/// insert location into the LocationToAssetId map
fn do_insert_location(asset_id: T::AssetId, location: VersionedMultiLocation) -> DispatchResult {
fn do_insert_location(asset_id: T::AssetId, location: VersionedLocation) -> DispatchResult {
// if the metadata contains a location, set the LocationToAssetId
let location: MultiLocation = location.try_into().map_err(|()| Error::<T>::BadVersion)?;
let location: Location = location.try_into().map_err(|()| Error::<T>::BadVersion)?;
LocationToAssetId::<T>::try_mutate(location, |maybe_asset_id| {
ensure!(maybe_asset_id.is_none(), Error::<T>::ConflictingLocation);
*maybe_asset_id = Some(asset_id);
Expand Down
Loading