Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add pallet-api/nonfungibles to runtime devnet #389

Open
wants to merge 1 commit into
base: chungquantin/feat-pallet_nonfungibles
Choose a base branch
from
Open
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
193 changes: 175 additions & 18 deletions runtime/devnet/src/config/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use sp_std::vec::Vec;
use versioning::*;

use crate::{
config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall, RuntimeEvent,
config::assets::{TrustBackedAssetsInstance, TrustBackedNftsInstance},
fungibles, nonfungibles, Runtime, RuntimeCall, RuntimeEvent,
};

mod versioning;
Expand All @@ -32,6 +33,9 @@ pub enum RuntimeRead {
/// Fungible token queries.
#[codec(index = 150)]
Fungibles(fungibles::Read<Runtime>),
/// Non-fungible token queries.
#[codec(index = 151)]
NonFungibles(nonfungibles::Read<Runtime>),
}

impl Readable for RuntimeRead {
Expand All @@ -43,30 +47,36 @@ impl Readable for RuntimeRead {
fn weight(&self) -> Weight {
match self {
RuntimeRead::Fungibles(key) => fungibles::Pallet::weight(key),
RuntimeRead::NonFungibles(key) => nonfungibles::Pallet::weight(key),
}
}

/// Performs the read and returns the result.
fn read(self) -> Self::Result {
match self {
RuntimeRead::Fungibles(key) => RuntimeResult::Fungibles(fungibles::Pallet::read(key)),
RuntimeRead::NonFungibles(key) =>
RuntimeResult::NonFungibles(nonfungibles::Pallet::read(key)),
}
}
}

/// The result of a runtime state read.
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq, Clone))]
#[cfg_attr(feature = "std", derive(PartialEq, Clone))]
pub enum RuntimeResult {
/// Fungible token read results.
Fungibles(fungibles::ReadResult<Runtime>),
/// Non-fungible token read results.
NonFungibles(nonfungibles::ReadResult<Runtime>),
}

impl RuntimeResult {
/// Encodes the result.
fn encode(&self) -> Vec<u8> {
match self {
RuntimeResult::Fungibles(result) => result.encode(),
RuntimeResult::NonFungibles(result) => result.encode(),
}
}
}
Expand All @@ -77,6 +87,12 @@ impl fungibles::Config for Runtime {
type WeightInfo = fungibles::weights::SubstrateWeight<Runtime>;
}

impl nonfungibles::Config for Runtime {
type NftsInstance = TrustBackedNftsInstance;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}

#[derive(Default)]
pub struct Config;
impl pallet_api::extension::Config for Config {
Expand Down Expand Up @@ -130,8 +146,8 @@ pub struct Filter<T>(PhantomData<T>);

impl<T: frame_system::Config<RuntimeCall = RuntimeCall>> Contains<RuntimeCall> for Filter<T> {
fn contains(c: &RuntimeCall) -> bool {
use fungibles::Call::*;
T::BaseCallFilter::contains(c) &&
let contain_fungibles: bool = {
use fungibles::Call::*;
matches!(
c,
RuntimeCall::Fungibles(
Expand All @@ -142,35 +158,73 @@ impl<T: frame_system::Config<RuntimeCall = RuntimeCall>> Contains<RuntimeCall> f
create { .. } | set_metadata { .. } |
start_destroy { .. } |
clear_metadata { .. } |
mint { .. } | burn { .. }
mint { .. } | burn { .. },
)
)
};

let contain_nonfungibles: bool = {
use nonfungibles::Call::*;
matches!(
c,
RuntimeCall::NonFungibles(
transfer { .. } |
approve { .. } | create { .. } |
destroy { .. } | set_metadata { .. } |
clear_metadata { .. } |
set_attribute { .. } |
clear_attribute { .. } |
approve_item_attributes { .. } |
cancel_item_attributes_approval { .. } |
mint { .. } | burn { .. } |
set_max_supply { .. },
)
)
};

T::BaseCallFilter::contains(c) && contain_fungibles | contain_nonfungibles
}
}

impl<T: frame_system::Config> Contains<RuntimeRead> for Filter<T> {
fn contains(r: &RuntimeRead) -> bool {
use fungibles::Read::*;
matches!(
r,
RuntimeRead::Fungibles(
TotalSupply(..) |
BalanceOf { .. } |
Allowance { .. } |
TokenName(..) | TokenSymbol(..) |
TokenDecimals(..) |
TokenExists(..)
let contain_fungibles: bool = {
use fungibles::Read::*;
matches!(
r,
RuntimeRead::Fungibles(
TotalSupply(..) |
BalanceOf { .. } | Allowance { .. } |
TokenName(..) | TokenSymbol(..) |
TokenDecimals(..) | TokenExists(..),
)
)
};
let contain_nonfungibles: bool = {
use nonfungibles::Read::*;
matches!(
r,
RuntimeRead::NonFungibles(
TotalSupply(..) |
BalanceOf { .. } | Allowance { .. } |
OwnerOf { .. } | GetAttribute { .. } |
Collection { .. } | NextCollectionId |
ItemMetadata { .. },
)
)
)
};

contain_fungibles | contain_nonfungibles
}
}

#[cfg(test)]
mod tests {
use codec::Encode;
use pallet_api::fungibles::Call::*;
use sp_core::crypto::AccountId32;
use RuntimeCall::{Balances, Fungibles};
use pallet_nfts::MintWitness;
use sp_core::{bounded_vec, crypto::AccountId32};
use RuntimeCall::{Balances, Fungibles, NonFungibles};

use super::*;

Expand All @@ -181,6 +235,10 @@ mod tests {
let value = 1_000;
let result = fungibles::ReadResult::<Runtime>::TotalSupply(value);
assert_eq!(RuntimeResult::Fungibles(result).encode(), value.encode());

let value = 1_000;
let result = nonfungibles::ReadResult::<Runtime>::TotalSupply(value);
assert_eq!(RuntimeResult::NonFungibles(result).encode(), value.encode());
}

#[test]
Expand Down Expand Up @@ -228,6 +286,76 @@ mod tests {
}
}

#[test]
fn filter_allows_nonfungibles_calls() {
use pallet_api::nonfungibles::{
Call::*, CollectionConfig, CollectionSettings, MintSettings,
};
use pallet_nfts::{CancelAttributesApprovalWitness, DestroyWitness};

for call in vec![
NonFungibles(transfer { collection: 0, item: 0, to: ACCOUNT }),
NonFungibles(approve {
collection: 0,
item: Some(0),
operator: ACCOUNT,
approved: false,
}),
NonFungibles(create {
admin: ACCOUNT,
config: CollectionConfig {
max_supply: Some(0),
mint_settings: MintSettings::default(),
settings: CollectionSettings::all_enabled(),
},
}),
NonFungibles(destroy {
collection: 0,
witness: DestroyWitness {
attributes: 0,
item_configs: 0,
item_metadatas: 0,
item_holders: 0,
allowances: 0,
},
}),
NonFungibles(set_attribute {
collection: 0,
item: Some(0),
namespace: pallet_nfts::AttributeNamespace::Pallet,
key: bounded_vec![],
value: bounded_vec![],
}),
NonFungibles(clear_attribute {
collection: 0,
item: Some(0),
namespace: pallet_nfts::AttributeNamespace::Pallet,
key: bounded_vec![],
}),
NonFungibles(set_metadata { collection: 0, item: 0, data: bounded_vec![] }),
NonFungibles(clear_metadata { collection: 0, item: 0 }),
NonFungibles(approve_item_attributes { collection: 0, item: 0, delegate: ACCOUNT }),
NonFungibles(cancel_item_attributes_approval {
collection: 0,
item: 0,
delegate: ACCOUNT,
witness: CancelAttributesApprovalWitness { account_attributes: 0 },
}),
NonFungibles(set_max_supply { collection: 0, max_supply: 0 }),
NonFungibles(mint {
to: ACCOUNT,
collection: 0,
item: 0,
witness: MintWitness { mint_price: None, owned_item: None },
}),
NonFungibles(burn { collection: 0, item: 0 }),
]
.iter()
{
assert!(Filter::<Runtime>::contains(call))
}
}

#[test]
fn filter_allows_fungibles_reads() {
use super::{fungibles::Read::*, RuntimeRead::*};
Expand All @@ -245,4 +373,33 @@ mod tests {
assert!(Filter::<Runtime>::contains(&read))
}
}

#[test]
fn filter_allows_nonfungibles_reads() {
use super::{nonfungibles::Read::*, RuntimeRead::*};

for read in vec![
NonFungibles(TotalSupply(1)),
NonFungibles(BalanceOf { collection: 1, owner: ACCOUNT }),
NonFungibles(Allowance {
collection: 1,
item: None,
owner: ACCOUNT,
operator: ACCOUNT,
}),
NonFungibles(OwnerOf { collection: 1, item: 1 }),
NonFungibles(GetAttribute {
collection: 0,
item: 0,
namespace: pallet_nfts::AttributeNamespace::CollectionOwner,
key: bounded_vec![],
}),
NonFungibles(Collection(1)),
NonFungibles(NextCollectionId),
]
.iter()
{
assert!(Filter::<Runtime>::contains(read))
}
}
}
21 changes: 16 additions & 5 deletions runtime/devnet/src/config/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use frame_system::{EnsureRoot, EnsureSigned};
use pallet_nfts::PalletFeatures;
use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId, Signature};
use sp_runtime::traits::Verify;
use sp_runtime::traits::{Get, Verify};

use crate::{
deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent,
Expand Down Expand Up @@ -37,7 +37,18 @@
pub const NftsMaxDeadlineDuration: BlockNumber = 12 * 30 * DAYS;
}

impl pallet_nfts::Config for Runtime {
#[derive(Debug)]
#[cfg_attr(feature = "std", derive(PartialEq, Clone))]
pub struct KeyLimit<const N: u32>;

Check warning on line 42 in runtime/devnet/src/config/assets.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct

warning: missing documentation for a struct --> runtime/devnet/src/config/assets.rs:42:1 | 42 | pub struct KeyLimit<const N: u32>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impl<const N: u32> Get<u32> for KeyLimit<N> {
fn get() -> u32 {
N
}
}

pub(crate) type TrustBackedNftsInstance = pallet_nfts::Instance1;
pub type TrustBackedNftsCall = pallet_nfts::Call<Runtime, TrustBackedNftsInstance>;

Check warning on line 50 in runtime/devnet/src/config/assets.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a type alias

warning: missing documentation for a type alias --> runtime/devnet/src/config/assets.rs:50:1 | 50 | pub type TrustBackedNftsCall = pallet_nfts::Call<Runtime, TrustBackedNftsInstance>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impl pallet_nfts::Config<TrustBackedNftsInstance> for Runtime {
// TODO: source from primitives
type ApprovalsLimit = ConstU32<20>;
type AttributeDepositBase = NftsAttributeDepositBase;
Expand All @@ -56,7 +67,7 @@
// TODO: source from primitives
type ItemId = ItemId;
// TODO: source from primitives
type KeyLimit = ConstU32<64>;
type KeyLimit = KeyLimit<64>;
type Locker = ();
type MaxAttributesPerCall = ConstU32<10>;
type MaxDeadlineDuration = NftsMaxDeadlineDuration;
Expand Down Expand Up @@ -86,8 +97,8 @@
type Deposit = AssetDeposit;
type NewAssetName = NewAssetName;
type NewAssetSymbol = NewAssetSymbol;
type NftCollectionId = <Self as pallet_nfts::Config>::CollectionId;
type NftId = <Self as pallet_nfts::Config>::ItemId;
type NftCollectionId = <Self as pallet_nfts::Config<TrustBackedNftsInstance>>::CollectionId;
type NftId = <Self as pallet_nfts::Config<TrustBackedNftsInstance>>::ItemId;
type Nfts = Nfts;
type PalletId = NftFractionalizationPalletId;
type RuntimeEvent = RuntimeEvent;
Expand All @@ -97,7 +108,7 @@
}

pub(crate) type TrustBackedAssetsInstance = pallet_assets::Instance1;
pub type TrustBackedAssetsCall = pallet_assets::Call<Runtime, TrustBackedAssetsInstance>;

Check warning on line 111 in runtime/devnet/src/config/assets.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a type alias

warning: missing documentation for a type alias --> runtime/devnet/src/config/assets.rs:111:1 | 111 | pub type TrustBackedAssetsCall = pallet_assets::Call<Runtime, TrustBackedAssetsInstance>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
type ApprovalDeposit = ApprovalDeposit;
type AssetAccountDeposit = AssetAccountDeposit;
Expand Down
38 changes: 19 additions & 19 deletions runtime/devnet/src/config/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use pop_runtime_common::proxy::{
};
use sp_runtime::traits::BlakeTwo256;

use super::assets::TrustBackedAssetsCall;
use super::assets::{TrustBackedAssetsCall, TrustBackedNftsCall};
use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent};

impl InstanceFilter<RuntimeCall> for ProxyType {
Expand Down Expand Up @@ -45,13 +45,13 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) |
RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) |
RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::create { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::destroy { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::redeposit { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::transfer_ownership { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::set_team { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::set_collection_max_supply { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::lock_collection { .. }) |
RuntimeCall::Utility { .. } |
RuntimeCall::Multisig { .. }
),
Expand All @@ -66,17 +66,17 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) |
RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) |
RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) |
RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::force_mint { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::update_mint_settings { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::mint_pre_signed { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::set_attributes_pre_signed { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::lock_item_transfer { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::unlock_item_transfer { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::lock_item_properties { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::set_metadata { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::clear_metadata { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::set_collection_metadata { .. }) |
RuntimeCall::Nfts(TrustBackedNftsCall::clear_collection_metadata { .. }) |
RuntimeCall::Utility { .. } |
RuntimeCall::Multisig { .. }
),
Expand Down
Loading
Loading