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
New Asset System - Prepare extension of Asset Manager (#1181)
* Add new asset types

* Add custom assets to runtime

* Add market assets to runtime

* Add pallet_assets benchmark and weights

* Expose MarketAssets call enum

* Update todo comment to incluse issue number

* Add campaign assets instance to runtime

* Cargo fmt

* Taplo fmt

* Refine asset class types

* Use efficient asset types

* Add all variants to overarching Asset enum

* Make MarketId compactable

* Adjust SerdeWrapper

Soon to be deprecated

* Make Battery Station compileable

* Make Zeitgeist compileable

* Cleanup code

* Remove NewForeignAsset

Conversion to compact encoding implies massive migration effort

* Implement asset type conversions

* Add Currency asset class

* Remove deprecated SerdeWrapper

* Add Currencies asset class

Also renames existing CurrencyId to Assets

* Add scale codec index matching tests

* Add asset conversion tests

* Update docstring

* Improve assets module structure

* Update license

* Update copyright

* Repair errorneous merge

* Update license

* Remove CombinatorialOutcome

* Improve tests

* Improve variable names

* Prettify code

Co-authored-by: Malte Kliemann <mail@maltekliemann.com>

* Fix conversion CampaignAssetId <> CampaignAssetClass

* Reorder asset enum variants

* Update runtime/zeitgeist/src/parameters.rs

Co-authored-by: Chralt <chralt.developer@gmail.com>

* Improve CurrencyClass docstring

Co-authored-by: Malte Kliemann <mail@maltekliemann.com>

---------

Co-authored-by: Malte Kliemann <mail@maltekliemann.com>
Co-authored-by: Chralt <chralt.developer@gmail.com>
  • Loading branch information
3 people authored Jan 12, 2024
commit 4628f8c0af5f44eab01add840fee8e7b78aced1e
87 changes: 0 additions & 87 deletions primitives/src/asset.rs

This file was deleted.

49 changes: 49 additions & 0 deletions primitives/src/assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2022-2024 Forecasting Technologies LTD.
// Copyright 2021-2022 Zeitgeist PM LLC.
//
// This file is part of Zeitgeist.
//
// Zeitgeist 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.
//
// Zeitgeist 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 Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

use crate::types::{CampaignAssetId, CategoryIndex, CustomAssetId, PoolId};
use parity_scale_codec::{Compact, CompactAs, Decode, Encode, HasCompact, MaxEncodedLen};
use scale_info::TypeInfo;

pub use all_assets::Asset;
pub use campaign_assets::CampaignAssetClass;
pub use currencies::CurrencyClass;
pub use custom_assets::CustomAssetClass;
pub use market_assets::MarketAssetClass;

mod all_assets;
mod campaign_assets;
mod currencies;
mod custom_assets;
mod market_assets;
#[cfg(test)]
mod tests;

/// In a scalar market, users can either choose a `Long` position,
/// meaning that they think the outcome will be closer to the upper bound
/// or a `Short` position meaning that they think the outcome will be closer
/// to the lower bound.
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[derive(
Clone, Copy, Debug, Decode, Eq, Encode, MaxEncodedLen, Ord, PartialEq, PartialOrd, TypeInfo,
)]
pub enum ScalarPosition {
Long,
Short,
}
152 changes: 152 additions & 0 deletions primitives/src/assets/all_assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// Copyright 2023-2024 Forecasting Technologies LTD.
//
// This file is part of Zeitgeist.
//
// Zeitgeist 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.
//
// Zeitgeist 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 Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

use super::*;

/// The `Asset` enum represents all types of assets available in the Zeitgeist
/// system.
///
/// This complete enumeration is intended to abstract the common interaction
/// with tokens away. For example, the developer is not forced to be aware
/// about which exact implementation will handle the desired asset class to
/// instruct operations such as `transfer` or `freeze`, instead it is
/// sufficient to call a crate that manages the routing.
/// While it is not recommended to use this enum in storage, it should not pose
/// a problem as long as all other asset types use the same scale encoding for
/// a matching asset variant in this enum.
///
/// **Deprecated:** Market and Pool assets are "lazy" migrated to
/// pallet-assets.
/// Do not create any new market or pool assets using the deprecated variants
/// in this enum.
///
/// # Types
///
/// * `MI`: Market Id
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[derive(
Clone,
Copy,
Debug,
Decode,
Default,
Eq,
Encode,
MaxEncodedLen,
Ord,
PartialEq,
PartialOrd,
TypeInfo,
)]
pub enum Asset<MI: MaxEncodedLen + HasCompact> {
#[codec(index = 0)]
CategoricalOutcome(MI, CategoryIndex),

#[codec(index = 1)]
ScalarOutcome(MI, ScalarPosition),

#[codec(index = 3)]
PoolShare(PoolId),

#[codec(index = 4)]
#[default]
Ztg,

#[codec(index = 5)]
ForeignAsset(u32),

#[codec(index = 6)]
ParimutuelShare(MI, CategoryIndex),

// "New" outcomes will replace the previous outcome types after the lazy
// migration completed
#[codec(index = 7)]
NewCategoricalOutcome(#[codec(compact)] MI, #[codec(compact)] CategoryIndex),

#[codec(index = 9)]
NewScalarOutcome(#[codec(compact)] MI, ScalarPosition),

#[codec(index = 10)]
NewParimutuelShare(#[codec(compact)] MI, #[codec(compact)] CategoryIndex),

#[codec(index = 11)]
NewPoolShare(#[codec(compact)] PoolId),

#[codec(index = 12)]
CampaignAssetClass(#[codec(compact)] CampaignAssetId),

#[codec(index = 13)]
CustomAssetClass(#[codec(compact)] CustomAssetId),
}

impl<MI: HasCompact + MaxEncodedLen> From<MarketAssetClass<MI>> for Asset<MI> {
fn from(value: MarketAssetClass<MI>) -> Self {
match value {
MarketAssetClass::<MI>::OldCategoricalOutcome(market_id, cat_id) => {
Self::CategoricalOutcome(market_id, cat_id)
}
MarketAssetClass::<MI>::OldScalarOutcome(market_id, scalar_pos) => {
Self::ScalarOutcome(market_id, scalar_pos)
}
MarketAssetClass::<MI>::OldParimutuelShare(market_id, cat_id) => {
Self::ParimutuelShare(market_id, cat_id)
}
MarketAssetClass::<MI>::OldPoolShare(pool_id) => Self::PoolShare(pool_id),
MarketAssetClass::<MI>::CategoricalOutcome(market_id, cat_id) => {
Self::NewCategoricalOutcome(market_id, cat_id)
}
MarketAssetClass::<MI>::ScalarOutcome(market_id, scalar_pos) => {
Self::NewScalarOutcome(market_id, scalar_pos)
}
MarketAssetClass::<MI>::ParimutuelShare(market_id, cat_id) => {
Self::NewParimutuelShare(market_id, cat_id)
}
MarketAssetClass::<MI>::PoolShare(pool_id) => Self::NewPoolShare(pool_id),
}
}
}

impl<MI: HasCompact + MaxEncodedLen> From<CampaignAssetClass> for Asset<MI> {
fn from(value: CampaignAssetClass) -> Self {
Self::CampaignAssetClass(value.0)
}
}

impl<MI: HasCompact + MaxEncodedLen> From<CustomAssetClass> for Asset<MI> {
fn from(value: CustomAssetClass) -> Self {
Self::CustomAssetClass(value.0)
}
}

impl<MI: HasCompact + MaxEncodedLen> From<CurrencyClass<MI>> for Asset<MI> {
fn from(value: CurrencyClass<MI>) -> Self {
match value {
CurrencyClass::<MI>::OldCategoricalOutcome(market_id, cat_id) => {
Self::CategoricalOutcome(market_id, cat_id)
}
CurrencyClass::<MI>::OldScalarOutcome(market_id, scalar_pos) => {
Self::ScalarOutcome(market_id, scalar_pos)
}
CurrencyClass::<MI>::OldParimutuelShare(market_id, cat_id) => {
Self::ParimutuelShare(market_id, cat_id)
}
CurrencyClass::<MI>::OldPoolShare(pool_id) => Self::PoolShare(pool_id),
CurrencyClass::<MI>::ForeignAsset(asset_id) => Self::ForeignAsset(asset_id),
}
}
}
51 changes: 51 additions & 0 deletions primitives/src/assets/campaign_assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2023-2024 Forecasting Technologies LTD.
//
// This file is part of Zeitgeist.
//
// Zeitgeist 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.
//
// Zeitgeist 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 Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

use super::*;

/// The `CampaignAsset` tuple struct represents all campaign assets.
/// Campaign assets can have special properties, such as the capability
/// to pay fees.
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[derive(
Clone, CompactAs, Copy, Debug, Decode, Default, Eq, Encode, MaxEncodedLen, PartialEq, TypeInfo,
)]
pub struct CampaignAssetClass(#[codec(compact)] pub(super) CampaignAssetId);

impl From<Compact<CampaignAssetId>> for CampaignAssetClass {
fn from(value: Compact<CampaignAssetId>) -> CampaignAssetClass {
CampaignAssetClass(value.into())
}
}

impl From<CampaignAssetClass> for Compact<CampaignAssetId> {
fn from(value: CampaignAssetClass) -> Compact<CampaignAssetId> {
value.0.into()
}
}

impl<MI: HasCompact + MaxEncodedLen> TryFrom<Asset<MI>> for CampaignAssetClass {
type Error = ();

fn try_from(value: Asset<MI>) -> Result<Self, Self::Error> {
match value {
Asset::<MI>::CampaignAssetClass(id) => Ok(Self(id)),
_ => Err(()),
}
}
}
Loading