Skip to content

Commit

Permalink
feat: add pallet-api/nonfungibles to runtime devnet
Browse files Browse the repository at this point in the history
  • Loading branch information
chungquantin committed Nov 19, 2024
1 parent 841035a commit 399695c
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 44 deletions.
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_support::{
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 @@ parameter_types! {
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 @@ impl pallet_nfts::Config for Runtime {
// 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 @@ impl pallet_nft_fractionalization::Config for Runtime {
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 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

0 comments on commit 399695c

Please sign in to comment.