From 55a89b2cf989ff3cff89e3ac06bbc2210289c7dd Mon Sep 17 00:00:00 2001 From: str-mv Date: Thu, 30 Jul 2020 06:19:45 +0000 Subject: [PATCH] Refactoring --- --- a/doc/demo_milestone1-2.md +++ b/doc/demo_milestone1-2.md @@ -52,7 +52,7 @@ Before running test, open [chain state tab](https://polkadot.js.org/apps/#/chainstate) and read `nft`.`nextCollectionId` state variable, which shows how many collections were created so far. If you just started the chain, this should equal 0. -Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics) and select ALICE account. Select `nft` module and `createCollection` method. Put 1 in `custom_data_sz` and run the transaction. After it is finalized, read the `nft`.`nextCollectionId` state variable. It will be equal 1. +Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics) and select ALICE account. Select `nft` module and `createCollection` method. Put 1 in `custom_data_size` and run the transaction. After it is finalized, read the `nft`.`nextCollectionId` state variable. It will be equal 1. Also, read the state variable `nft`.`collection` with ID = 1 (Because everything in NFT Palette is numbered from 1, not from 0). You will see something like this: --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -1,14 +1,9 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; -/// A FRAME pallet template with necessary imports - -/// Feel free to remove or edit this file as needed. -/// If you change the name of this file, make sure to update its references in runtime/src/lib.rs -/// If you remove this file, you can remove those references - /// For more guidance on Substrate FRAME, see the example pallet /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs + +use codec::{Decode, Encode}; use frame_support::{decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure}; use frame_system::{self as system, ensure_signed}; use sp_runtime::sp_std::prelude::Vec; @@ -19,11 +14,37 @@ #[cfg(test)] mod tests; +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +pub enum AccessMode { + Normal, + WhiteList, +} +impl Default for AccessMode { fn default() -> Self { Self::Normal } } + +#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)] +pub enum CollectionMode { + Invalid, + NFT, + Fungible, + ReFungible, +} +impl Default for CollectionMode { fn default() -> Self { Self::Invalid } } + #[derive(Encode, Decode, Default, Clone, PartialEq)] #[cfg_attr(feature = "std", derive(Debug))] +pub struct Ownership { + pub owner: AccountId, + pub fraction: u128 +} + +#[derive(Encode, Decode, Default, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] pub struct CollectionType { pub owner: AccountId, + pub mode: CollectionMode, + pub access: AccessMode, pub next_item_id: u64, + pub decimal_points: u32, pub name: Vec, // 64 include null escape char pub description: Vec, // 256 include null escape char pub token_prefix: Vec, // 16 include null escape char @@ -45,55 +66,61 @@ pub data: Vec, } -/// The pallet's configuration trait. -pub trait Trait: system::Trait { - // Add other types and constants required to configure this pallet. +#[derive(Encode, Decode, Default, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct FungibleItemType { + pub collection: u64, + pub owner: Vec, + pub data: Vec, +} + +#[derive(Encode, Decode, Default, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct ReFungibleItemType { + pub collection: u64, + pub owner: Vec>, +} - /// The overarching event type. +pub trait Trait: system::Trait { type Event: From> + Into<::Event>; } -// This pallet's storage items. decl_storage! { - // It is important to update your storage name so that your pallet's - // storage items are isolated from other pallets. trait Store for Module as Nft { - /// Next available collection ID - pub NextCollectionID get(fn next_collection_id): u64; + // Next available collection ID + NextCollectionID get(fn next_collection_id): u64; pub Collection get(fn collection): map hasher(identity) u64 => CollectionType; pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec; - /// Balance owner per collection map - pub Balance get(fn balance_count): map hasher(blake2_128_concat) (u64, T::AccountId) => u64; - pub ApprovedList get(fn approved): map hasher(blake2_128_concat) (u64, u64) => Vec; + // Balance owner per collection map + pub Balance get(fn balance_count): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => u64; + pub ApprovedList get(fn approved): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => Vec; - pub ItemList get(fn item_id): map hasher(blake2_128_concat) (u64, u64) => NftItemType; - pub ItemListIndex get(fn item_index): map hasher(blake2_128_concat) u64 => u64; + // Item collections + pub NftItemList get(fn nft_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType; + pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType; + pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType; + ItemListIndex get(fn item_index): map hasher(blake2_128_concat) u64 => u64; - pub AddressTokens get(fn address_tokens): map hasher(blake2_128_concat) (u64, T::AccountId) => Vec; + pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec; } } -// The pallet's events decl_event!( pub enum Event where AccountId = ::AccountId, { - Created(u64, AccountId), + Created(u64, CollectionMode, AccountId), ItemCreated(u64, u64), ItemDestroyed(u64, u64), } ); -// The pallet's dispatchable functions. decl_module! { - /// The module declaration. pub struct Module for enum Call where origin: T::Origin { - // Initializing events - // this is needed only if you are using events in your pallet fn deposit_event() = default; // Create collection of NFT with given parameters @@ -105,12 +132,33 @@ collection_name: Vec, collection_description: Vec, token_prefix: Vec, - custom_data_sz: u32) -> DispatchResult { + mode: CollectionMode, + decimal_points: u32, + custom_data_size: u32) -> DispatchResult { // Anyone can create a collection let who = ensure_signed(origin)?; + // check type + ensure!((mode == CollectionMode::Fungible || mode == CollectionMode::NFT || mode == CollectionMode::ReFungible), + "Collection mode must be Fungible, NFT or ReFungible"); + + // NFT checks + if mode == CollectionMode::NFT + { + ensure!(decimal_points == 0, "Collection in NFT mode must have zero in decimal_points parameter"); + } + + // Fungible checks + if mode == CollectionMode::Fungible + { + ensure!(custom_data_size == 0, "Collection in Fungible mode must have zero in custom_data_size parameter"); + ensure!(decimal_points != 0, "Collection in Fungible mode must have not zero in decimal_points parameter"); + } + // check params + ensure!(decimal_points < 100, "decimal_points parameter must be lower than 100"); + let mut name = collection_name.to_vec(); name.push(0); ensure!(name.len() <= 64, "Collection name can not be longer than 63 char"); @@ -134,17 +182,20 @@ let new_collection = CollectionType { owner: who.clone(), name: name, + mode: mode.clone(), + access: AccessMode::Normal, description: description, + decimal_points: decimal_points, token_prefix: prefix, next_item_id: next_id, - custom_data_size: custom_data_sz, + custom_data_size: custom_data_size, }; // Add new collection to map >::insert(next_id, new_collection); // call event - Self::deposit_event(RawEvent::Created(next_id, who.clone())); + Self::deposit_event(RawEvent::Created(next_id, mode.clone(), who.clone())); Ok(()) } @@ -153,10 +204,13 @@ pub fn destroy_collection(origin, collection_id: u64) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + Self::check_owner_permissions(collection_id, sender)?; - let owner = >::get(collection_id).owner; - ensure!(sender == owner, "You do not own this collection"); + >::remove_prefix(collection_id); + >::remove_prefix(collection_id); + >::remove_prefix(collection_id); + ::remove(collection_id); + >::remove(collection_id); >::remove(collection_id); Ok(()) @@ -166,11 +220,8 @@ pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); - + Self::check_owner_permissions(collection_id, sender)?; let mut target_collection = >::get(collection_id); - ensure!(sender == target_collection.owner, "You do not own this collection"); - target_collection.owner = new_owner; >::insert(collection_id, target_collection); @@ -181,23 +232,11 @@ pub fn add_collection_admin(origin, collection_id: u64, new_admin_id: T::AccountId) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + Self::check_owner_or_admin_permissions(collection_id, sender)?; + let mut admin_arr: Vec = Vec::new(); - let target_collection = >::get(collection_id); - let is_owner = sender == target_collection.owner; - - let no_perm_mes = "You do not have permissions to modify this collection"; - let exists = >::contains_key(collection_id); - - if !is_owner + if >::contains_key(collection_id) { - ensure!(exists, no_perm_mes); - ensure!(>::get(collection_id).contains(&sender), no_perm_mes); - } - - let mut admin_arr: Vec = Vec::new(); - if exists - { admin_arr = >::get(collection_id); ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role"); } @@ -212,21 +251,9 @@ pub fn remove_collection_admin(origin, collection_id: u64, account_id: T::AccountId) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); - - let target_collection = >::get(collection_id); - let is_owner = sender == target_collection.owner; - - let no_perm_mes = "You do not have permissions to modify this collection"; - let exists = >::contains_key(collection_id); - - if !is_owner - { - ensure!(exists, no_perm_mes); - ensure!(>::get(collection_id).contains(&sender), no_perm_mes); - } + Self::check_owner_or_admin_permissions(collection_id, sender)?; - if exists + if >::contains_key(collection_id) { let mut admin_arr = >::get(collection_id); admin_arr.retain(|i| *i != account_id); @@ -237,46 +264,36 @@ } #[weight = 0] - pub fn create_item(origin, collection_id: u64, properties: Vec) -> DispatchResult { + pub fn create_item(origin, collection_id: u64, properties: Vec, owner: T::AccountId) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + // check size let target_collection = >::get(collection_id); ensure!(target_collection.custom_data_size >= properties.len() as u32, "Size of item is too large"); - let is_owner = sender == target_collection.owner; - let no_perm_mes = "You do not have permissions to modify this collection"; - let exists = >::contains_key(collection_id); + Self::check_owner_or_admin_permissions(collection_id, sender.clone())?; - if !is_owner - { - ensure!(exists, no_perm_mes); - ensure!(>::get(collection_id).contains(&sender), no_perm_mes); - } + let new_balance = >::get(collection_id, sender.clone()) + 1; + >::insert(collection_id, sender.clone(), new_balance); - let new_balance = >::get((collection_id, sender.clone())) + 1; - >::insert((collection_id, sender.clone()), new_balance); + // TODO: implement other modes + ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented"); - // Create new item - let new_item = NftItemType { - collection: collection_id, - owner: sender, - data: properties, - }; - - - let current_index = ::get(collection_id) - .checked_add(1) - .expect("Item list index id error"); + if target_collection.mode == CollectionMode::NFT + { + // Create nft item + let item = NftItemType { + collection: collection_id, + owner: owner, + data: properties, + }; - Self::add_token_index(collection_id, current_index, new_item.owner.clone())?; - - ::insert(collection_id, current_index); - >::insert((collection_id, current_index), new_item); + Self::add_nft_item(item)?; + } // call event - Self::deposit_event(RawEvent::ItemCreated(collection_id, current_index)); + Self::deposit_event(RawEvent::ItemCreated(collection_id, ::get(collection_id))); Ok(()) } @@ -285,33 +302,9 @@ pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); - - let target_collection = >::get(collection_id); - let is_owner = sender == target_collection.owner; - - ensure!(>::contains_key((collection_id, item_id)), "Item does not exists"); - let item = >::get((collection_id, item_id)); - - if !is_owner - { - // check if item owner - if item.owner != sender - { - let no_perm_mes = "You do not have permissions to modify this collection"; - - ensure!(>::contains_key(collection_id), no_perm_mes); - ensure!(>::get(collection_id).contains(&sender), no_perm_mes); - } - } - >::remove((collection_id, item_id)); + Self::check_owner_or_admin_permissions(collection_id, sender.clone())?; + Self::burn_nft_item(collection_id, item_id)?; - Self::remove_token_index(collection_id, item_id, item.owner.clone())?; - - // update balance - let new_balance = >::get((collection_id, item.owner.clone())) - 1; - >::insert((collection_id, item.owner.clone()), new_balance); - // call event Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id)); @@ -319,49 +312,21 @@ } #[weight = 0] - pub fn transfer(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult { + pub fn transfer(origin, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + Self::check_owner_or_admin_permissions(collection_id, sender)?; let target_collection = >::get(collection_id); - let is_owner = sender == target_collection.owner; - ensure!(>::contains_key((collection_id, item_id)), "Item does not exists"); - let mut item = >::get((collection_id, item_id)); + // TODO: implement other modes + ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented"); - if !is_owner + if target_collection.mode == CollectionMode::NFT { - // check if item owner - if item.owner != sender - { - let no_perm_mes = "You do not have permissions to modify this collection"; - - ensure!(>::contains_key(collection_id), no_perm_mes); - ensure!(>::get(collection_id).contains(&sender), no_perm_mes); - } + Self::transfer_nft(collection_id, item_id, recipient)?; } - >::remove((collection_id, item_id)); - // update balance - let balance_old_owner = >::get((collection_id, item.owner.clone())) - 1; - >::insert((collection_id, item.owner.clone()), balance_old_owner); - - let balance_new_owner = >::get((collection_id, new_owner.clone())) + 1; - >::insert((collection_id, new_owner.clone()), balance_new_owner); - - // change owner - let old_owner = item.owner.clone(); - item.owner = new_owner.clone(); - >::insert((collection_id, item_id), item); - - // update index collection - Self::move_token_index(collection_id, item_id, old_owner, new_owner.clone())?; - - // reset approved list - let itm: Vec = Vec::new(); - >::insert((collection_id, item_id), itm); - Ok(()) } @@ -369,30 +334,17 @@ pub fn approve(origin, approved: T::AccountId, collection_id: u64, item_id: u64) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); - let target_collection = >::get(collection_id); - let is_owner = sender == target_collection.owner; - - ensure!(>::contains_key((collection_id, item_id)), "Item does not exists"); - let item = >::get((collection_id, item_id)); - - if !is_owner + let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id); + if !item_owner { - // check if item owner - if item.owner != sender - { - let no_perm_mes = "You do not have permissions to modify this collection"; - - ensure!(>::contains_key(collection_id), no_perm_mes); - ensure!(>::get(collection_id).contains(&sender), no_perm_mes); - } + Self::check_owner_or_admin_permissions(collection_id, sender.clone())?; } - let list_exists = >::contains_key((collection_id, item_id)); + let list_exists = >::contains_key(collection_id, item_id); if list_exists { - let mut list = >::get((collection_id, item_id)); + let mut list = >::get(collection_id, item_id); let item_contains = list.contains(&approved.clone()); if !item_contains { @@ -402,36 +354,53 @@ let mut itm = Vec::new(); itm.push(approved.clone()); - >::insert((collection_id, item_id), itm); + >::insert(collection_id, item_id, itm); } Ok(()) } #[weight = 0] - pub fn transfer_from(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult { + pub fn transfer_from(origin, recipient: T::AccountId, collection_id: u64, item_id: u64, ) -> DispatchResult { + + let mut approved: bool = false; + let sender = ensure_signed(origin)?; + let approved_list_exists = >::contains_key(collection_id, item_id); + if approved_list_exists + { + let list_itm = >::get(collection_id, item_id); + approved = list_itm.contains(&recipient.clone()); + } - let no_perm_mes = "You do not have permissions to modify this collection"; - ensure!(>::contains_key((collection_id, item_id)), no_perm_mes); - let list_itm = >::get((collection_id, item_id)); - ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes); + if !approved + { + Self::check_owner_or_admin_permissions(collection_id, sender)?; + } + + let target_collection = >::get(collection_id); - Self::transfer(origin, collection_id, item_id, new_owner)?; + // TODO: implement other modes + ensure!(target_collection.mode == CollectionMode::NFT, "Collection type not implemented"); + if target_collection.mode == CollectionMode::NFT + { + Self::transfer_nft(collection_id, item_id, recipient)?; + } + Ok(()) } #[weight = 0] pub fn safe_transfer_from(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult { - let no_perm_mes = "You do not have permissions to modify this collection"; - ensure!(>::contains_key((collection_id, item_id)), no_perm_mes); - let list_itm = >::get((collection_id, item_id)); - ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes); + // let no_perm_mes = "You do not have permissions to modify this collection"; + // ensure!(>::contains_key((collection_id, item_id)), no_perm_mes); + // let list_itm = >::get((collection_id, item_id)); + // ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes); - // on_nft_received call + // // on_nft_received call - Self::transfer(origin, collection_id, item_id, new_owner)?; + // Self::transfer(origin, collection_id, item_id, new_owner)?; Ok(()) } @@ -439,21 +408,137 @@ } impl Module { + + fn collection_exists(collection_id: u64) -> DispatchResult{ + ensure!(>::contains_key(collection_id), "This collection does not exist"); + Ok(()) + } + + fn check_owner_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult { + + Self::collection_exists(collection_id)?; + + let target_collection = >::get(collection_id); + ensure!(subject == target_collection.owner, "You do not own this collection"); + + Ok(()) + } + + fn check_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult { + + Self::collection_exists(collection_id)?; + + let target_collection = >::get(collection_id); + let is_owner = subject == target_collection.owner; + + let no_perm_mes = "You do not have permissions to modify this collection"; + let exists = >::contains_key(collection_id); + + if !is_owner + { + ensure!(exists, no_perm_mes); + ensure!(>::get(collection_id).contains(&subject), no_perm_mes); + } + Ok(()) + } + + fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool{ + + let mut result = false; + let target_collection = >::get(collection_id); + + if target_collection.mode == CollectionMode::NFT + { + let item = >::get(collection_id, item_id); + result = item.owner == subject; + } + + if target_collection.mode == CollectionMode::Fungible + { + let item = >::get(collection_id, item_id); + result = item.owner.contains(&subject); + } + + if target_collection.mode == CollectionMode::ReFungible + { + let item = >::get(collection_id, item_id); + result = item.owner.iter().any(|i| i.owner == subject); + } + + result + } + + fn add_nft_item(item: NftItemType) -> DispatchResult { + + let current_index = ::get(item.collection) + .checked_add(1) + .expect("Item list index id error"); + + Self::add_token_index(item.collection, current_index, item.owner.clone())?; + + ::insert(item.collection, current_index); + >::insert(item.collection, current_index, item); + + Ok(()) + } + + fn burn_nft_item(collection_id: u64, item_id: u64) -> DispatchResult { + + let item = >::get(collection_id, item_id); + Self::remove_token_index(collection_id, item_id, item.owner.clone())?; + + // update balance + let new_balance = >::get(collection_id, item.owner.clone()).checked_sub(1).unwrap(); + >::insert(collection_id, item.owner.clone(), new_balance); + >::remove(collection_id, item_id); + + Ok(()) + } + + fn transfer_nft(collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult { + + let mut item = >::get(collection_id, item_id); + + // update balance + let balance_old_owner = >::get(collection_id, item.owner.clone()).checked_sub(1).unwrap(); + >::insert(collection_id, item.owner.clone(), balance_old_owner); + + let balance_new_owner = >::get(collection_id, new_owner.clone()).checked_add(1).unwrap(); + >::insert(collection_id, new_owner.clone(), balance_new_owner); + + // change owner + let old_owner = item.owner.clone(); + item.owner = new_owner.clone(); + >::insert(collection_id, item_id, item); + + // update index collection + Self::move_token_index(collection_id, item_id, old_owner, new_owner.clone())?; + + // reset approved list + let itm: Vec = Vec::new(); + >::insert(collection_id, item_id, itm); + + // remove item + >::remove(collection_id, item_id); + + Ok(()) + } + fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult { - let list_exists = >::contains_key((collection_id, owner.clone())); + let list_exists = >::contains_key(collection_id, owner.clone()); if list_exists { - let mut list = >::get((collection_id, owner.clone())); + let mut list = >::get(collection_id, owner.clone()); let item_contains = list.contains(&item_index.clone()); if !item_contains { list.push(item_index.clone()); } - >::insert((collection_id, owner.clone()), list); + >::insert(collection_id, owner.clone(), list); } else { let mut itm = Vec::new(); itm.push(item_index.clone()); - >::insert((collection_id, owner), itm); + >::insert(collection_id, owner, itm); } Ok(()) @@ -464,14 +549,14 @@ item_index: u64, owner: T::AccountId, ) -> DispatchResult { - let list_exists = >::contains_key((collection_id, owner.clone())); + let list_exists = >::contains_key(collection_id, owner.clone()); if list_exists { - let mut list = >::get((collection_id, owner.clone())); + let mut list = >::get(collection_id, owner.clone()); let item_contains = list.contains(&item_index.clone()); if item_contains { list.retain(|&item| item != item_index); - >::insert((collection_id, owner), list); + >::insert(collection_id, owner, list); } } --- a/pallets/nft/src/mock.rs +++ b/pallets/nft/src/mock.rs @@ -1,14 +1,20 @@ // Creating mock runtime here use crate::{Module, Trait}; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; use frame_system as system; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup, Saturating}, Perbill, }; +use frame_support::{ + parameter_types, impl_outer_origin, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}, + Weight, + }, +}; impl_outer_origin! { pub enum Origin for Test {} @@ -24,7 +30,10 @@ pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() + .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get(); } + impl system::Trait for Test { type Origin = Origin; type Call = (); @@ -40,6 +49,11 @@ type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; + type BaseCallFilter = (); + type DbWeight = RocksDbWeight; + type BlockExecutionWeight = BlockExecutionWeight; + type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumExtrinsicWeight; type Version = (); type ModuleToIndex = (); type AccountData = (); -- gitstuff