Skip to content
multiasset.rs 29.6 KiB
Newer Older
// Copyright (C) Parity Technologies (UK) Ltd.
Gavin Wood's avatar
Gavin Wood committed
// This file is part of Polkadot.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.

//! Cross-Consensus Message format asset data structures.
//!
//! This encompasses four types for representing assets:
//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some
//!   amount of a fungible.
//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with
//!   fungibles first.
//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific
//!   kind.
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently
//!   filtering an XCM holding account.
Gavin Wood's avatar
Gavin Wood committed

use super::{InteriorMultiLocation, MultiLocation};
use crate::v2::{
	AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility,
	MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter,
	MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility,
	WildMultiAsset as OldWildMultiAsset,
};
use alloc::{vec, vec::Vec};
use core::{
	cmp::Ordering,
	convert::{TryFrom, TryInto},
};
use parity_scale_codec::{self as codec, Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use bounded_collections::{BoundedVec, ConstU32};
Gavin Wood's avatar
Gavin Wood committed

/// A general identifier for an instance of a non-fungible asset class.
#[derive(
	Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub enum AssetInstance {
	/// Undefined - used if the non-fungible asset class has only one instance.
	Undefined,

	/// A compact index. Technically this could be greater than `u128`, but this implementation
	/// supports only values up to `2**128 - 1`.
Gavin Wood's avatar
Gavin Wood committed
	Index(#[codec(compact)] u128),

	/// A 4-byte fixed-length datum.
	Array4([u8; 4]),

	/// An 8-byte fixed-length datum.
	Array8([u8; 8]),

	/// A 16-byte fixed-length datum.
	Array16([u8; 16]),

	/// A 32-byte fixed-length datum.
	Array32([u8; 32]),
}

impl TryFrom<OldAssetInstance> for AssetInstance {
	type Error = ();
	fn try_from(value: OldAssetInstance) -> Result<Self, Self::Error> {
		use OldAssetInstance::*;
		Ok(match value {
			Undefined => Self::Undefined,
			Index(n) => Self::Index(n),
			Array4(n) => Self::Array4(n),
			Array8(n) => Self::Array8(n),
			Array16(n) => Self::Array16(n),
			Array32(n) => Self::Array32(n),
			Blob(_) => return Err(()),
		})
	}
}

impl From<()> for AssetInstance {
	fn from(_: ()) -> Self {
		Self::Undefined
	}
}

impl From<[u8; 4]> for AssetInstance {
	fn from(x: [u8; 4]) -> Self {
		Self::Array4(x)
	}
}

impl From<[u8; 8]> for AssetInstance {
	fn from(x: [u8; 8]) -> Self {
		Self::Array8(x)
	}
}

impl From<[u8; 16]> for AssetInstance {
	fn from(x: [u8; 16]) -> Self {
		Self::Array16(x)
	}
}

impl From<[u8; 32]> for AssetInstance {
	fn from(x: [u8; 32]) -> Self {
		Self::Array32(x)
	}
}

impl From<u8> for AssetInstance {
	fn from(x: u8) -> Self {
		Self::Index(x as u128)
	}
}

impl From<u16> for AssetInstance {
	fn from(x: u16) -> Self {
		Self::Index(x as u128)
	}
}

impl From<u32> for AssetInstance {
	fn from(x: u32) -> Self {
		Self::Index(x as u128)
	}
}

impl From<u64> for AssetInstance {
	fn from(x: u64) -> Self {
		Self::Index(x as u128)
	}
}

impl TryFrom<AssetInstance> for () {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Undefined => Ok(()),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 4] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array4(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 8] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array8(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 16] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array16(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 32] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array32(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for u8 {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Index(x) => x.try_into().map_err(|_| ()),
			_ => Err(()),
		}
	}
}

Loading full blame...