difftreelog
feat api for recursive item burning
in: master
17 files changed
pallets/common/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/common/src/benchmarking.rs
+++ b/pallets/common/src/benchmarking.rs
@@ -20,8 +20,8 @@
use frame_benchmarking::{benchmarks, account};
use up_data_structs::{
CollectionMode, CreateCollectionData, CollectionId, Property, PropertyKey, PropertyValue,
- MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
- OFFCHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, MAX_PROPERTIES_PER_ITEM,
+ CollectionPermissions, NestingRule, MAX_COLLECTION_NAME_LENGTH,
+ MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, MAX_PROPERTIES_PER_ITEM,
};
use frame_support::{
traits::{Currency, Get},
@@ -74,15 +74,15 @@
}
pub fn create_collection_raw<T: Config, R>(
- owner: T::AccountId,
+ owner: T::CrossAccountId,
mode: CollectionMode,
handler: impl FnOnce(
- T::AccountId,
+ T::CrossAccountId,
CreateCollectionData<T::AccountId>,
) -> Result<CollectionId, DispatchError>,
cast: impl FnOnce(CollectionHandle<T>) -> R,
) -> Result<R, DispatchError> {
- T::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());
+ <T as Config>::Currency::deposit_creating(&owner.as_sub(), T::CollectionCreationPrice::get());
let name = create_u16_data::<MAX_COLLECTION_NAME_LENGTH>();
let description = create_u16_data::<MAX_COLLECTION_DESCRIPTION_LENGTH>();
let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
@@ -93,13 +93,19 @@
name,
description,
token_prefix,
+ permissions: Some(CollectionPermissions {
+ nesting: Some(NestingRule::Permissive),
+ ..Default::default()
+ }),
..Default::default()
},
)
.and_then(CollectionHandle::try_get)
.map(cast)
}
-fn create_collection<T: Config>(owner: T::AccountId) -> Result<CollectionHandle<T>, DispatchError> {
+fn create_collection<T: Config>(
+ owner: T::CrossAccountId,
+) -> Result<CollectionHandle<T>, DispatchError> {
create_collection_raw(
owner,
CollectionMode::NFT,
@@ -127,7 +133,7 @@
bench_init!($($rest)*);
};
($name:ident: collection($owner:ident); $($rest:tt)*) => {
- let $name = create_collection::<T>($owner.clone())?;
+ let $name = create_collection::<T>(T::CrossAccountId::from_sub($owner.clone()))?;
bench_init!($($rest)*);
};
($name:ident: cross; $($rest:tt)*) => {
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -1168,8 +1168,9 @@
);
Ok(new_limit)
}
+
pub fn clamp_permissions(
- mode: CollectionMode,
+ _mode: CollectionMode,
old_limit: &CollectionPermissions,
mut new_limit: CollectionPermissions,
) -> Result<CollectionPermissions, DispatchError> {
@@ -1204,6 +1205,22 @@
fn approve() -> Weight;
fn transfer_from() -> Weight;
fn burn_from() -> Weight;
+
+ /// Differs from burn_item in case of Fungible and Refungible, as it should burn
+ /// whole users's balance
+ ///
+ /// This method shouldn't be used directly, as it doesn't count breadth price, use `burn_recursively` instead
+ fn burn_recursively_self_raw() -> Weight;
+ /// Cost of iterating over `amount` children while burning, without counting child burning itself
+ ///
+ /// This method shouldn't be used directly, as it doesn't count depth price, use `burn_recursively` instead
+ fn burn_recursively_breadth_raw(amount: u32) -> Weight;
+
+ fn burn_recursively(max_selfs: u32, max_breadth: u32) -> Weight {
+ Self::burn_recursively_self_raw()
+ .saturating_mul(max_selfs.max(1) as u64)
+ .saturating_add(Self::burn_recursively_breadth_raw(max_breadth))
+ }
}
pub trait CommonCollectionOperations<T: Config> {
@@ -1233,6 +1250,13 @@
token: TokenId,
amount: u128,
) -> DispatchResultWithPostInfo;
+ fn burn_item_recursively(
+ &self,
+ sender: T::CrossAccountId,
+ token: TokenId,
+ self_budget: &dyn Budget,
+ breadth_budget: &dyn Budget,
+ ) -> DispatchResultWithPostInfo;
fn set_collection_properties(
&self,
sender: T::CrossAccountId,
pallets/fungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/fungible/src/benchmarking.rs
+++ b/pallets/fungible/src/benchmarking.rs
@@ -25,7 +25,9 @@
const SEED: u32 = 1;
-fn create_collection<T: Config>(owner: T::AccountId) -> Result<FungibleHandle<T>, DispatchError> {
+fn create_collection<T: Config>(
+ owner: T::CrossAccountId,
+) -> Result<FungibleHandle<T>, DispatchError> {
create_collection_raw(
owner,
CollectionMode::Fungible(0),
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -16,9 +16,10 @@
use core::marker::PhantomData;
-use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
+use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, traits::Get};
use up_data_structs::{TokenId, CollectionId, CreateItemExData, budget::Budget, CreateItemData};
use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
+use pallet_structure::Error as StructureError;
use sp_runtime::ArithmeticError;
use sp_std::{vec::Vec, vec};
use up_data_structs::{Property, PropertyKey, PropertyValue, PropertyKeyPermission};
@@ -91,6 +92,16 @@
fn burn_from() -> Weight {
<SelfWeightOf<T>>::burn_from()
}
+
+ fn burn_recursively_self_raw() -> Weight {
+ // Read to get total balance
+ Self::burn_item() + T::DbWeight::get().reads(1)
+ }
+
+ fn burn_recursively_breadth_raw(_amount: u32) -> Weight {
+ // Fungible tokens can't have children
+ 0
+ }
}
impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {
@@ -170,6 +181,26 @@
)
}
+ fn burn_item_recursively(
+ &self,
+ sender: T::CrossAccountId,
+ token: TokenId,
+ self_budget: &dyn Budget,
+ _breadth_budget: &dyn Budget,
+ ) -> DispatchResultWithPostInfo {
+ // Should not happen?
+ ensure!(
+ token == TokenId::default(),
+ <Error<T>>::FungibleItemsHaveNoId
+ );
+ ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);
+
+ with_weight(
+ <Pallet<T>>::burn(self, &sender, <Balance<T>>::get((self.id, &sender))),
+ <CommonWeights<T>>::burn_recursively_self_raw(),
+ )
+ }
+
fn transfer(
&self,
from: T::CrossAccountId,
pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -18,12 +18,9 @@
use crate::{Pallet, Config, NonfungibleHandle};
use sp_std::prelude::*;
-use pallet_common::benchmarking::{create_collection_raw, create_data, property_key, property_value};
+use pallet_common::benchmarking::{create_collection_raw, property_key, property_value};
use frame_benchmarking::{benchmarks, account};
-use up_data_structs::{
- CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,
- budget::Unlimited,
-};
+use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};
use pallet_common::bench_init;
const SEED: u32 = 1;
@@ -49,7 +46,7 @@
}
fn create_collection<T: Config>(
- owner: T::AccountId,
+ owner: T::CrossAccountId,
) -> Result<NonfungibleHandle<T>, DispatchError> {
create_collection_raw(
owner,
@@ -96,6 +93,26 @@
let item = create_max_item(&collection, &sender, burner.clone())?;
}: {<Pallet<T>>::burn(&collection, &burner, item)?}
+ burn_recursively_self_raw {
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ sender: cross_from_sub(owner); burner: cross_sub;
+ };
+ let item = create_max_item(&collection, &sender, burner.clone())?;
+ }: {<Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)}
+
+ burn_recursively_breadth_plus_self_plus_self_per_each_raw {
+ let b in 0..200;
+ bench_init!{
+ owner: sub; collection: collection(owner);
+ sender: cross_from_sub(owner); burner: cross_sub;
+ };
+ let item = create_max_item(&collection, &sender, burner.clone())?;
+ for i in 0..b {
+ create_max_item(&collection, &sender, T::CrossTokenAddressMapping::token_to_address(collection.id, item))?;
+ }
+ }: {<Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)}
+
transfer {
bench_init!{
owner: sub; collection: collection(owner);
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -108,6 +108,15 @@
fn burn_from() -> Weight {
<SelfWeightOf<T>>::burn_from()
}
+
+ fn burn_recursively_self_raw() -> Weight {
+ <SelfWeightOf<T>>::burn_recursively_self_raw()
+ }
+
+ fn burn_recursively_breadth_raw(amount: u32) -> Weight {
+ <SelfWeightOf<T>>::burn_recursively_breadth_plus_self_plus_self_per_each_raw(amount)
+ .saturating_sub(Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1))
+ }
}
fn map_create_data<T: Config>(
@@ -264,6 +273,16 @@
}
}
+ fn burn_item_recursively(
+ &self,
+ sender: T::CrossAccountId,
+ token: TokenId,
+ self_budget: &dyn Budget,
+ breadth_budget: &dyn Budget,
+ ) -> DispatchResultWithPostInfo {
+ <Pallet<T>>::burn_recursively(self, &sender, token, self_budget, breadth_budget)
+ }
+
fn transfer(
&self,
from: T::CrossAccountId,
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -18,7 +18,13 @@
use erc::ERC721Events;
use evm_coder::ToLog;
-use frame_support::{BoundedVec, ensure, fail, transactional, storage::with_transaction};
+use frame_support::{
+ BoundedVec, ensure, fail, transactional,
+ storage::with_transaction,
+ pallet_prelude::DispatchResultWithPostInfo,
+ pallet_prelude::Weight,
+ weights::{PostDispatchInfo, Pays},
+};
use up_data_structs::{
AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,
mapping::TokenAddressMapping, NestingRule, budget::Budget, Property, PropertyPermission,
@@ -29,7 +35,7 @@
Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, CollectionHandle,
eth::collection_id_to_address,
};
-use pallet_structure::Pallet as PalletStructure;
+use pallet_structure::{Pallet as PalletStructure, Error as StructureError};
use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
use sp_core::H160;
use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};
@@ -39,6 +45,7 @@
use scale_info::TypeInfo;
pub use pallet::*;
+use weights::WeightInfo;
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;
pub mod common;
@@ -373,7 +380,7 @@
<PalletCommon<T>>::deposit_event(CommonEvent::Approved(
collection.id,
token,
- sender.clone(),
+ token_data.owner.clone(),
old_spender,
0,
));
@@ -396,6 +403,45 @@
Ok(())
}
+ #[transactional]
+ pub fn burn_recursively(
+ collection: &NonfungibleHandle<T>,
+ sender: &T::CrossAccountId,
+ token: TokenId,
+ self_budget: &dyn Budget,
+ breadth_budget: &dyn Budget,
+ ) -> DispatchResultWithPostInfo {
+ ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);
+
+ let current_token_account =
+ T::CrossTokenAddressMapping::token_to_address(collection.id, token);
+
+ let mut weight = 0 as Weight;
+
+ // This method is transactional, if user in fact doesn't have permissions to remove token -
+ // tokens removed here will be restored after rejected transaction
+ for ((collection, token), _) in <TokenChildren<T>>::iter_prefix((collection.id, token)) {
+ ensure!(breadth_budget.consume(), <StructureError<T>>::BreadthLimit,);
+ let PostDispatchInfo { actual_weight, .. } =
+ <PalletStructure<T>>::burn_item_recursively(
+ current_token_account.clone(),
+ collection,
+ token,
+ self_budget,
+ breadth_budget,
+ )?;
+ if let Some(actual_weight) = actual_weight {
+ weight = weight.saturating_add(actual_weight);
+ }
+ }
+
+ Self::burn(collection, sender, token)?;
+ DispatchResultWithPostInfo::Ok(PostDispatchInfo {
+ actual_weight: Some(weight + <SelfWeightOf<T>>::burn_item()),
+ pays_fee: Pays::Yes,
+ })
+ }
+
pub fn set_token_property(
collection: &NonfungibleHandle<T>,
sender: &T::CrossAccountId,
@@ -964,6 +1010,7 @@
);
ensure_sender_allowed::<T>(handle.id, under, from, sender, nesting_budget)?
}
+ NestingRule::Permissive => {}
}
Ok(())
}
pallets/nonfungible/src/weights.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -92,7 +92,35 @@
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
-
+ // Storage: Nonfungible TokenChildren (r:1 w:0)
+ // Storage: Nonfungible TokenData (r:1 w:1)
+ // Storage: Nonfungible TokensBurnt (r:1 w:1)
+ // Storage: Nonfungible AccountBalance (r:1 w:1)
+ // Storage: Nonfungible Allowance (r:1 w:0)
+ // Storage: Nonfungible Owned (r:0 w:1)
+ // Storage: Nonfungible TokenProperties (r:0 w:1)
+ fn burn_recursively_self_raw() -> Weight {
+ (86_136_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(5 as Weight))
+ .saturating_add(T::DbWeight::get().writes(5 as Weight))
+ }
+ // Storage: Nonfungible TokenChildren (r:1 w:0)
+ // Storage: Nonfungible TokenData (r:1 w:1)
+ // Storage: Nonfungible TokensBurnt (r:1 w:1)
+ // Storage: Nonfungible AccountBalance (r:1 w:1)
+ // Storage: Nonfungible Allowance (r:1 w:0)
+ // Storage: Nonfungible Owned (r:0 w:1)
+ // Storage: Nonfungible TokenProperties (r:0 w:1)
+ // Storage: Common CollectionById (r:1 w:0)
+ fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {
+ (0 as Weight)
+ // Standard Error: 42_828_000
+ .saturating_add((381_478_000 as Weight).saturating_mul(b as Weight))
+ .saturating_add(T::DbWeight::get().reads(6 as Weight))
+ .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))
+ .saturating_add(T::DbWeight::get().writes(5 as Weight))
+ .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
+ }
// Storage: Nonfungible TokenData (r:1 w:1)
// Storage: Nonfungible AccountBalance (r:2 w:2)
// Storage: Nonfungible Allowance (r:1 w:0)
pallets/refungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -50,7 +50,9 @@
Ok(TokenId(<TokensMinted<T>>::get(&collection.id)))
}
-fn create_collection<T: Config>(owner: T::AccountId) -> Result<RefungibleHandle<T>, DispatchError> {
+fn create_collection<T: Config>(
+ owner: T::CrossAccountId,
+) -> Result<RefungibleHandle<T>, DispatchError> {
create_collection_raw(
owner,
CollectionMode::NFT,
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -17,12 +17,13 @@
use core::marker::PhantomData;
use sp_std::collections::btree_map::BTreeMap;
-use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};
+use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, traits::Get};
use up_data_structs::{
CollectionId, TokenId, CreateItemExData, CreateRefungibleExData, budget::Budget, Property,
PropertyKey, PropertyValue, PropertyKeyPermission, CreateItemData,
};
use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
+use pallet_structure::Error as StructureError;
use sp_runtime::DispatchError;
use sp_std::{vec::Vec, vec};
@@ -113,6 +114,15 @@
fn burn_from() -> Weight {
<SelfWeightOf<T>>::burn_from()
}
+
+ fn burn_recursively_self_raw() -> Weight {
+ // Read to get total balance
+ Self::burn_item() + T::DbWeight::get().reads(1)
+ }
+ fn burn_recursively_breadth_raw(_amount: u32) -> Weight {
+ // Refungible token can't have children
+ 0
+ }
}
fn map_create_data<T: Config>(
@@ -205,6 +215,25 @@
)
}
+ fn burn_item_recursively(
+ &self,
+ sender: T::CrossAccountId,
+ token: TokenId,
+ self_budget: &dyn Budget,
+ _breadth_budget: &dyn Budget,
+ ) -> DispatchResultWithPostInfo {
+ ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);
+ with_weight(
+ <Pallet<T>>::burn(
+ self,
+ &sender,
+ token,
+ <Balance<T>>::get((self.id, token, &sender)),
+ ),
+ <CommonWeights<T>>::burn_recursively_self_raw(),
+ )
+ }
+
fn transfer(
&self,
from: T::CrossAccountId,
pallets/scheduler/src/lib.rsdiffbeforeafterboth--- a/pallets/scheduler/src/lib.rs
+++ b/pallets/scheduler/src/lib.rs
@@ -43,8 +43,9 @@
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
-#[cfg(feature = "runtime-benchmarks")]
-mod benchmarking;
+// FIXME
+// #[cfg(feature = "runtime-benchmarks")]
+// mod benchmarking;
pub mod weights;
pallets/structure/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/structure/src/benchmarking.rs
+++ b/pallets/structure/src/benchmarking.rs
@@ -5,6 +5,7 @@
use up_data_structs::{
CreateCollectionData, CollectionMode, CreateItemData, CreateNftData, budget::Unlimited,
};
+use pallet_common::Config as CommonConfig;
use pallet_evm::account::CrossAccountId;
const SEED: u32 = 1;
@@ -14,8 +15,8 @@
let caller: T::AccountId = account("caller", 0, SEED);
let caller_cross = T::CrossAccountId::from_sub(caller.clone());
- T::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
- T::CollectionDispatch::create(caller, CreateCollectionData {
+ <T as CommonConfig>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
+ T::CollectionDispatch::create(caller_cross.clone(), CreateCollectionData {
mode: CollectionMode::NFT,
..Default::default()
})?;
pallets/structure/src/lib.rsdiffbeforeafterboth--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -3,7 +3,7 @@
use pallet_common::CommonCollectionOperations;
use sp_std::collections::btree_set::BTreeSet;
-use frame_support::dispatch::{DispatchError, DispatchResult};
+use frame_support::dispatch::{DispatchError, DispatchResult, DispatchResultWithPostInfo};
use frame_support::fail;
pub use pallet::*;
use pallet_common::{dispatch::CollectionDispatch, CollectionHandle};
@@ -29,6 +29,8 @@
OuroborosDetected,
/// While searched for owner, encountered depth limit
DepthLimit,
+ /// While iterating over children, encountered breadth limit
+ BreadthLimit,
/// While searched for owner, found token owner by not-yet-existing token
TokenNotFound,
}
@@ -184,6 +186,19 @@
Err(<Error<T>>::DepthLimit.into())
}
+ pub fn burn_item_recursively(
+ from: T::CrossAccountId,
+ collection: CollectionId,
+ token: TokenId,
+ self_budget: &dyn Budget,
+ breadth_budget: &dyn Budget,
+ ) -> DispatchResultWithPostInfo {
+ let handle = <CollectionHandle<T>>::try_get(collection)?;
+ let dispatch = T::CollectionDispatch::dispatch(handle);
+ let dispatch = dispatch.as_dyn();
+ dispatch.burn_item_recursively(from.clone(), token, self_budget, breadth_budget)
+ }
+
pub fn check_nesting(
from: T::CrossAccountId,
under: &T::CrossAccountId,
pallets/unique/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/unique/src/benchmarking.rs
+++ b/pallets/unique/src/benchmarking.rs
@@ -22,7 +22,10 @@
use frame_support::traits::{tokens::currency::Currency, Get};
use frame_benchmarking::{benchmarks, account};
use sp_runtime::DispatchError;
-use pallet_common::benchmarking::{create_data, create_var_data, create_u16_data};
+use pallet_common::{
+ Config as CommonConfig,
+ benchmarking::{create_data, create_u16_data},
+};
const SEED: u32 = 1;
@@ -30,7 +33,7 @@
owner: T::AccountId,
mode: CollectionMode,
) -> Result<CollectionId, DispatchError> {
- T::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());
+ <T as CommonConfig>::Currency::deposit_creating(&owner, T::CollectionCreationPrice::get());
let col_name = create_u16_data::<MAX_COLLECTION_NAME_LENGTH>();
let col_desc = create_u16_data::<MAX_COLLECTION_DESCRIPTION_LENGTH>();
let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
@@ -54,7 +57,7 @@
let token_prefix = create_data::<MAX_TOKEN_PREFIX_LENGTH>();
let mode: CollectionMode = CollectionMode::NFT;
let caller: T::AccountId = account("caller", 0, SEED);
- T::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
+ <T as CommonConfig>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
}: _(RawOrigin::Signed(caller.clone()), col_name.clone(), col_desc.clone(), token_prefix.clone(), mode)
verify {
assert_eq!(<pallet_common::CollectionById<T>>::get(CollectionId(1)).unwrap().owner, caller);
@@ -77,16 +80,6 @@
let collection = create_nft_collection::<T>(caller.clone())?;
<Pallet<T>>::add_to_allow_list(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(allowlist_account.clone()))?;
}: _(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(allowlist_account))
-
- set_public_access_mode {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- }: _(RawOrigin::Signed(caller.clone()), collection, AccessMode::AllowList)
-
- set_mint_permission {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- }: _(RawOrigin::Signed(caller.clone()), collection, true)
change_collection_owner {
let caller: T::AccountId = account("caller", 0, SEED);
@@ -145,7 +138,6 @@
owner_can_transfer: Some(true),
sponsored_data_rate_limit: None,
transfers_enabled: Some(true),
- nesting_rule: None,
};
}: set_collection_limits(RawOrigin::Signed(caller.clone()), collection, cl)
}
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -469,6 +469,8 @@
#[derivative(Debug(format_with = "bounded::set_debug"))]
BoundedBTreeSet<CollectionId, ConstU32<16>>,
),
+ /// Used for tests
+ Permissive,
}
#[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
runtime/common/src/weights.rsdiffbeforeafterboth--- a/runtime/common/src/weights.rs
+++ b/runtime/common/src/weights.rs
@@ -89,4 +89,12 @@
fn burn_from() -> Weight {
dispatch_weight::<T>() + max_weight_of!(burn_from())
}
+
+ fn burn_recursively_self_raw() -> Weight {
+ max_weight_of!(burn_recursively_self_raw())
+ }
+
+ fn burn_recursively_breadth_raw(amount: u32) -> Weight {
+ max_weight_of!(burn_recursively_breadth_raw(amount))
+ }
}
runtime/unique/src/lib.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.1819#![cfg_attr(not(feature = "std"), no_std)]20// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.21#![recursion_limit = "1024"]22#![allow(clippy::from_over_into, clippy::identity_op)]23#![allow(clippy::fn_to_numeric_cast_with_truncation)]24// Make the WASM binary available.25#[cfg(feature = "std")]26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));2728use sp_api::impl_runtime_apis;29use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};30use sp_runtime::DispatchError;31// #[cfg(any(feature = "std", test))]32// pub use sp_runtime::BuildStorage;3334use sp_runtime::{35 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,36 generic::Era,37 traits::{38 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf, Saturating,39 CheckedConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion,40 Zero, Member,41 },42 transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},43 ApplyExtrinsicResult, RuntimeAppPublic, SaturatedConversion, DispatchErrorWithPostInfo,44};4546use fp_self_contained::{SelfContainedCall, CheckedSignature};47use sp_std::{cmp::Ordering, marker::PhantomData};48use pallet_unq_scheduler::DispatchCall;4950use sp_std::prelude::*;5152#[cfg(feature = "std")]53use sp_version::NativeVersion;54use sp_version::RuntimeVersion;55pub use pallet_transaction_payment::{56 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,57};58// A few exports that help ease life for downstream crates.59pub use pallet_balances::Call as BalancesCall;60pub use pallet_evm::{61 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _, OnMethodCall,62 Account as EVMAccount, FeeCalculator, GasWeightMapping,63};64pub use frame_support::{65 construct_runtime, match_types,66 dispatch::DispatchResult,67 PalletId, parameter_types, StorageValue, ConsensusEngineId,68 traits::{69 tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,70 Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,71 OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,72 },73 weights::{74 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},75 DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,76 WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,77 },78};79// use pallet_contracts::weights::WeightInfo;80// #[cfg(any(feature = "std", test))]81use frame_system::{82 self as frame_system, EnsureRoot, EnsureSigned,83 limits::{BlockWeights, BlockLength},84};85use sp_arithmetic::{86 traits::{BaseArithmetic, Unsigned},87};88use smallvec::smallvec;89use codec::{Encode, Decode};90use fp_rpc::TransactionStatus;9192// pub use pallet_timestamp::Call as TimestampCall;9394// Polkadot imports95use pallet_xcm::XcmPassthrough;96use polkadot_parachain::primitives::Sibling;97use up_data_structs::{98 CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits, 99 CollectionStats, RpcCollection, 100 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping}101};102use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};103use xcm_builder::{104 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,105 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,106 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,107 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,108 ParentIsPreset,109};110use xcm_executor::{Config, XcmExecutor, Assets};111112use xcm::latest::{113 // Xcm,114 AssetId::{Concrete},115 Fungibility::Fungible as XcmFungible,116 MultiAsset,117 Error as XcmError,118};119use xcm_executor::traits::{MatchesFungible, WeightTrader};120121use unique_runtime_common::{122 impl_common_runtime_apis,123 types::*,124 constants::*,125 dispatch::{CollectionDispatchT, CollectionDispatch},126 sponsoring::UniqueSponsorshipHandler,127 eth_sponsoring::UniqueEthSponsorshipHandler,128 weights::CommonWeights,129};130131pub const RUNTIME_NAME: &str = "unique";132pub const TOKEN_SYMBOL: &str = "UNQ";133134type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;135136impl RuntimeInstance for Runtime {137 type CrossAccountId = self::CrossAccountId;138139 type TransactionConverter = self::TransactionConverter;140141 fn get_transaction_converter() -> TransactionConverter {142 TransactionConverter143 }144}145146/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know147/// the specifics of the runtime. They can then be made to be agnostic over specific formats148/// of data like extrinsics, allowing for them to continue syncing the network through upgrades149/// to even the core data structures.150pub mod opaque {151 use sp_std::prelude::*;152 use sp_runtime::impl_opaque_keys;153 use super::Aura;154155 pub use unique_runtime_common::types::*;156157 impl_opaque_keys! {158 pub struct SessionKeys {159 pub aura: Aura,160 }161 }162}163164/// This runtime version.165pub const VERSION: RuntimeVersion = RuntimeVersion {166 spec_name: create_runtime_str!(RUNTIME_NAME),167 impl_name: create_runtime_str!(RUNTIME_NAME),168 authoring_version: 1,169 spec_version: 922000,170 impl_version: 0,171 apis: RUNTIME_API_VERSIONS,172 transaction_version: 1,173 state_version: 0,174};175176#[derive(codec::Encode, codec::Decode)]177pub enum XCMPMessage<XAccountId, XBalance> {178 /// Transfer tokens to the given account from the Parachain account.179 TransferToken(XAccountId, XBalance),180}181182/// The version information used to identify this runtime when compiled natively.183#[cfg(feature = "std")]184pub fn native_version() -> NativeVersion {185 NativeVersion {186 runtime_version: VERSION,187 can_author_with: Default::default(),188 }189}190191type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;192193pub struct DealWithFees;194impl OnUnbalanced<NegativeImbalance> for DealWithFees {195 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {196 if let Some(fees) = fees_then_tips.next() {197 // for fees, 100% to treasury198 let mut split = fees.ration(100, 0);199 if let Some(tips) = fees_then_tips.next() {200 // for tips, if any, 100% to treasury201 tips.ration_merge_into(100, 0, &mut split);202 }203 Treasury::on_unbalanced(split.0);204 // Author::on_unbalanced(split.1);205 }206 }207}208209parameter_types! {210 pub const BlockHashCount: BlockNumber = 2400;211 pub RuntimeBlockLength: BlockLength =212 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);213 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);214 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;215 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()216 .base_block(BlockExecutionWeight::get())217 .for_class(DispatchClass::all(), |weights| {218 weights.base_extrinsic = ExtrinsicBaseWeight::get();219 })220 .for_class(DispatchClass::Normal, |weights| {221 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);222 })223 .for_class(DispatchClass::Operational, |weights| {224 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);225 // Operational transactions have some extra reserved space, so that they226 // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.227 weights.reserved = Some(228 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT229 );230 })231 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)232 .build_or_panic();233 pub const Version: RuntimeVersion = VERSION;234 pub const SS58Prefix: u16 = 7391;235}236237parameter_types! {238 pub const ChainId: u64 = 8880;239}240241pub struct FixedFee;242impl FeeCalculator for FixedFee {243 fn min_gas_price() -> (U256, u64) {244 (MIN_GAS_PRICE.into(), 0)245 }246}247248// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case249// (contract, which only writes a lot of data),250// approximating on top of our real store write weight251parameter_types! {252 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;253 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;254 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();255}256257/// Limiting EVM execution to 50% of block for substrate users and management tasks258/// EVM transaction consumes more weight than substrate's, so we can't rely on them being259/// scheduled fairly260const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);261parameter_types! {262 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());263}264265pub enum FixedGasWeightMapping {}266impl GasWeightMapping for FixedGasWeightMapping {267 fn gas_to_weight(gas: u64) -> Weight {268 gas.saturating_mul(WeightPerGas::get())269 }270 fn weight_to_gas(weight: Weight) -> u64 {271 weight / WeightPerGas::get()272 }273}274275impl pallet_evm::Config for Runtime {276 type BlockGasLimit = BlockGasLimit;277 type FeeCalculator = FixedFee;278 type GasWeightMapping = FixedGasWeightMapping;279 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;280 type CallOrigin = EnsureAddressTruncated<Self>;281 type WithdrawOrigin = EnsureAddressTruncated<Self>;282 type AddressMapping = HashedAddressMapping<Self::Hashing>;283 type PrecompilesType = ();284 type PrecompilesValue = ();285 type Currency = Balances;286 type Event = Event;287 type OnMethodCall = (288 pallet_evm_migration::OnMethodCall<Self>,289 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,290 CollectionDispatchT<Self>,291 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,292 );293 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;294 type ChainId = ChainId;295 type Runner = pallet_evm::runner::stack::Runner<Self>;296 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;297 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;298 type FindAuthor = EthereumFindAuthor<Aura>;299}300301impl pallet_evm_migration::Config for Runtime {302 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;303}304305pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);306impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {307 fn find_author<'a, I>(digests: I) -> Option<H160>308 where309 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,310 {311 if let Some(author_index) = F::find_author(digests) {312 let authority_id = Aura::authorities()[author_index as usize].clone();313 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));314 }315 None316 }317}318319impl pallet_ethereum::Config for Runtime {320 type Event = Event;321 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;322}323324impl pallet_randomness_collective_flip::Config for Runtime {}325326impl frame_system::Config for Runtime {327 /// The data to be stored in an account.328 type AccountData = pallet_balances::AccountData<Balance>;329 /// The identifier used to distinguish between accounts.330 type AccountId = AccountId;331 /// The basic call filter to use in dispatchable.332 type BaseCallFilter = Everything;333 /// Maximum number of block number to block hash mappings to keep (oldest pruned first).334 type BlockHashCount = BlockHashCount;335 /// The maximum length of a block (in bytes).336 type BlockLength = RuntimeBlockLength;337 /// The index type for blocks.338 type BlockNumber = BlockNumber;339 /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.340 type BlockWeights = RuntimeBlockWeights;341 /// The aggregated dispatch type that is available for extrinsics.342 type Call = Call;343 /// The weight of database operations that the runtime can invoke.344 type DbWeight = RocksDbWeight;345 /// The ubiquitous event type.346 type Event = Event;347 /// The type for hashing blocks and tries.348 type Hash = Hash;349 /// The hashing algorithm used.350 type Hashing = BlakeTwo256;351 /// The header type.352 type Header = generic::Header<BlockNumber, BlakeTwo256>;353 /// The index type for storing how many extrinsics an account has signed.354 type Index = Index;355 /// The lookup mechanism to get account ID from whatever is passed in dispatchers.356 type Lookup = AccountIdLookup<AccountId, ()>;357 /// What to do if an account is fully reaped from the system.358 type OnKilledAccount = ();359 /// What to do if a new account is created.360 type OnNewAccount = ();361 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;362 /// The ubiquitous origin type.363 type Origin = Origin;364 /// This type is being generated by `construct_runtime!`.365 type PalletInfo = PalletInfo;366 /// This is used as an identifier of the chain. 42 is the generic substrate prefix.367 type SS58Prefix = SS58Prefix;368 /// Weight information for the extrinsics of this pallet.369 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;370 /// Version of the runtime.371 type Version = Version;372 type MaxConsumers = ConstU32<16>;373}374375parameter_types! {376 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;377}378379impl pallet_timestamp::Config for Runtime {380 /// A timestamp: milliseconds since the unix epoch.381 type Moment = u64;382 type OnTimestampSet = ();383 type MinimumPeriod = MinimumPeriod;384 type WeightInfo = ();385}386387parameter_types! {388 // pub const ExistentialDeposit: u128 = 500;389 pub const ExistentialDeposit: u128 = 0;390 pub const MaxLocks: u32 = 50;391}392393impl pallet_balances::Config for Runtime {394 type MaxLocks = MaxLocks;395 type MaxReserves = ();396 type ReserveIdentifier = [u8; 16];397 /// The type for recording an account's balance.398 type Balance = Balance;399 /// The ubiquitous event type.400 type Event = Event;401 type DustRemoval = Treasury;402 type ExistentialDeposit = ExistentialDeposit;403 type AccountStore = System;404 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;405}406407pub const fn deposit(items: u32, bytes: u32) -> Balance {408 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE409}410411/*412parameter_types! {413 pub TombstoneDeposit: Balance = deposit(414 1,415 sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,416 );417 pub DepositPerContract: Balance = TombstoneDeposit::get();418 pub const DepositPerStorageByte: Balance = deposit(0, 1);419 pub const DepositPerStorageItem: Balance = deposit(1, 0);420 pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);421 pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;422 pub const SignedClaimHandicap: u32 = 2;423 pub const MaxDepth: u32 = 32;424 pub const MaxValueSize: u32 = 16 * 1024;425 pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb426 // The lazy deletion runs inside on_initialize.427 pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *428 RuntimeBlockWeights::get().max_block;429 // The weight needed for decoding the queue should be less or equal than a fifth430 // of the overall weight dedicated to the lazy deletion.431 pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (432 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -433 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)434 )) / 5) as u32;435 pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();436}437438impl pallet_contracts::Config for Runtime {439 type Time = Timestamp;440 type Randomness = RandomnessCollectiveFlip;441 type Currency = Balances;442 type Event = Event;443 type RentPayment = ();444 type SignedClaimHandicap = SignedClaimHandicap;445 type TombstoneDeposit = TombstoneDeposit;446 type DepositPerContract = DepositPerContract;447 type DepositPerStorageByte = DepositPerStorageByte;448 type DepositPerStorageItem = DepositPerStorageItem;449 type RentFraction = RentFraction;450 type SurchargeReward = SurchargeReward;451 type WeightPrice = pallet_transaction_payment::Pallet<Self>;452 type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;453 type ChainExtension = NFTExtension;454 type DeletionQueueDepth = DeletionQueueDepth;455 type DeletionWeightLimit = DeletionWeightLimit;456 type Schedule = Schedule;457 type CallStack = [pallet_contracts::Frame<Self>; 31];458}459*/460461parameter_types! {462 /// This value increases the priority of `Operational` transactions by adding463 /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.464 pub const OperationalFeeMultiplier: u8 = 5;465}466467/// Linear implementor of `WeightToFeePolynomial`468pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);469470impl<T> WeightToFeePolynomial for LinearFee<T>471where472 T: BaseArithmetic + From<u32> + Copy + Unsigned,473{474 type Balance = T;475476 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {477 smallvec!(WeightToFeeCoefficient {478 // Targeting 0.1 Unique per NFT transfer479 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),480 coeff_frac: Perbill::zero(),481 negative: false,482 degree: 1,483 })484 }485}486487impl pallet_transaction_payment::Config for Runtime {488 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;489 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;490 type OperationalFeeMultiplier = OperationalFeeMultiplier;491 type WeightToFee = LinearFee<Balance>;492 type FeeMultiplierUpdate = ();493}494495parameter_types! {496 pub const ProposalBond: Permill = Permill::from_percent(5);497 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;498 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;499 pub const SpendPeriod: BlockNumber = 5 * MINUTES;500 pub const Burn: Permill = Permill::from_percent(0);501 pub const TipCountdown: BlockNumber = 1 * DAYS;502 pub const TipFindersFee: Percent = Percent::from_percent(20);503 pub const TipReportDepositBase: Balance = 1 * UNIQUE;504 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;505 pub const BountyDepositBase: Balance = 1 * UNIQUE;506 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;507 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");508 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;509 pub const MaximumReasonLength: u32 = 16384;510 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);511 pub const BountyValueMinimum: Balance = 5 * UNIQUE;512 pub const MaxApprovals: u32 = 100;513}514515impl pallet_treasury::Config for Runtime {516 type PalletId = TreasuryModuleId;517 type Currency = Balances;518 type ApproveOrigin = EnsureRoot<AccountId>;519 type RejectOrigin = EnsureRoot<AccountId>;520 type Event = Event;521 type OnSlash = ();522 type ProposalBond = ProposalBond;523 type ProposalBondMinimum = ProposalBondMinimum;524 type ProposalBondMaximum = ProposalBondMaximum;525 type SpendPeriod = SpendPeriod;526 type Burn = Burn;527 type BurnDestination = ();528 type SpendFunds = ();529 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;530 type MaxApprovals = MaxApprovals;531}532533impl pallet_sudo::Config for Runtime {534 type Event = Event;535 type Call = Call;536}537538pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);539540impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider541 for RelayChainBlockNumberProvider<T>542{543 type BlockNumber = BlockNumber;544545 fn current_block_number() -> Self::BlockNumber {546 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()547 .map(|d| d.relay_parent_number)548 .unwrap_or_default()549 }550}551552parameter_types! {553 pub const MinVestedTransfer: Balance = 10 * UNIQUE;554 pub const MaxVestingSchedules: u32 = 28;555}556557impl orml_vesting::Config for Runtime {558 type Event = Event;559 type Currency = pallet_balances::Pallet<Runtime>;560 type MinVestedTransfer = MinVestedTransfer;561 type VestedTransferOrigin = EnsureSigned<AccountId>;562 type WeightInfo = ();563 type MaxVestingSchedules = MaxVestingSchedules;564 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;565}566567parameter_types! {568 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;569 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;570}571572impl cumulus_pallet_parachain_system::Config for Runtime {573 type Event = Event;574 type SelfParaId = parachain_info::Pallet<Self>;575 type OnSystemEvent = ();576 // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<577 // MaxDownwardMessageWeight,578 // XcmExecutor<XcmConfig>,579 // Call,580 // >;581 type OutboundXcmpMessageSource = XcmpQueue;582 type DmpMessageHandler = DmpQueue;583 type ReservedDmpWeight = ReservedDmpWeight;584 type ReservedXcmpWeight = ReservedXcmpWeight;585 type XcmpMessageHandler = XcmpQueue;586}587588impl parachain_info::Config for Runtime {}589590impl cumulus_pallet_aura_ext::Config for Runtime {}591592parameter_types! {593 pub const RelayLocation: MultiLocation = MultiLocation::parent();594 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;595 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();596 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();597}598599/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used600/// when determining ownership of accounts for asset transacting and when attempting to use XCM601/// `Transact` in order to determine the dispatch Origin.602pub type LocationToAccountId = (603 // The parent (Relay-chain) origin converts to the default `AccountId`.604 ParentIsPreset<AccountId>,605 // Sibling parachain origins convert to AccountId via the `ParaId::into`.606 SiblingParachainConvertsVia<Sibling, AccountId>,607 // Straight up local `AccountId32` origins just alias directly to `AccountId`.608 AccountId32Aliases<RelayNetwork, AccountId>,609);610611pub struct OnlySelfCurrency;612impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {613 fn matches_fungible(a: &MultiAsset) -> Option<B> {614 match (&a.id, &a.fun) {615 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),616 _ => None,617 }618 }619}620621/// Means for transacting assets on this chain.622pub type LocalAssetTransactor = CurrencyAdapter<623 // Use this currency:624 Balances,625 // Use this currency when it is a fungible asset matching the given location or name:626 OnlySelfCurrency,627 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:628 LocationToAccountId,629 // Our chain's account ID type (we can't get away without mentioning it explicitly):630 AccountId,631 // We don't track any teleports.632 (),633>;634635/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,636/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can637/// biases the kind of local `Origin` it will become.638pub type XcmOriginToTransactDispatchOrigin = (639 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location640 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for641 // foreign chains who want to have a local sovereign account on this chain which they control.642 SovereignSignedViaLocation<LocationToAccountId, Origin>,643 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when644 // recognised.645 RelayChainAsNative<RelayOrigin, Origin>,646 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when647 // recognised.648 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,649 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a650 // transaction from the Root origin.651 ParentAsSuperuser<Origin>,652 // Native signed account converter; this just converts an `AccountId32` origin into a normal653 // `Origin::Signed` origin of the same 32-byte value.654 SignedAccountId32AsNative<RelayNetwork, Origin>,655 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.656 XcmPassthrough<Origin>,657);658659parameter_types! {660 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.661 pub UnitWeightCost: Weight = 1_000_000;662 // 1200 UNIQUEs buy 1 second of weight.663 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);664 pub const MaxInstructions: u32 = 100;665 pub const MaxAuthorities: u32 = 100_000;666}667668match_types! {669 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {670 MultiLocation { parents: 1, interior: Here } |671 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }672 };673}674675pub type Barrier = (676 TakeWeightCredit,677 AllowTopLevelPaidExecutionFrom<Everything>,678 AllowUnpaidExecutionFrom<ParentOrParentsUnitPlurality>,679 // ^^^ Parent & its unit plurality gets free execution680);681682pub struct UsingOnlySelfCurrencyComponents<683 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,684 AssetId: Get<MultiLocation>,685 AccountId,686 Currency: CurrencyT<AccountId>,687 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,688>(689 Weight,690 Currency::Balance,691 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,692);693impl<694 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,695 AssetId: Get<MultiLocation>,696 AccountId,697 Currency: CurrencyT<AccountId>,698 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,699 > WeightTrader700 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>701{702 fn new() -> Self {703 Self(0, Zero::zero(), PhantomData)704 }705706 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {707 let amount = WeightToFee::calc(&weight);708 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;709710 // location to this parachain through relay chain711 let option1: xcm::v1::AssetId = Concrete(MultiLocation {712 parents: 1,713 interior: X1(Parachain(ParachainInfo::parachain_id().into())),714 });715 // direct location716 let option2: xcm::v1::AssetId = Concrete(MultiLocation {717 parents: 0,718 interior: Here,719 });720721 let required = if payment.fungible.contains_key(&option1) {722 (option1, u128_amount).into()723 } else if payment.fungible.contains_key(&option2) {724 (option2, u128_amount).into()725 } else {726 (Concrete(MultiLocation::default()), u128_amount).into()727 };728729 let unused = payment730 .checked_sub(required)731 .map_err(|_| XcmError::TooExpensive)?;732 self.0 = self.0.saturating_add(weight);733 self.1 = self.1.saturating_add(amount);734 Ok(unused)735 }736737 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {738 let weight = weight.min(self.0);739 let amount = WeightToFee::calc(&weight);740 self.0 -= weight;741 self.1 = self.1.saturating_sub(amount);742 let amount: u128 = amount.saturated_into();743 if amount > 0 {744 Some((AssetId::get(), amount).into())745 } else {746 None747 }748 }749}750impl<751 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,752 AssetId: Get<MultiLocation>,753 AccountId,754 Currency: CurrencyT<AccountId>,755 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,756 > Drop757 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>758{759 fn drop(&mut self) {760 OnUnbalanced::on_unbalanced(Currency::issue(self.1));761 }762}763764pub struct XcmConfig;765impl Config for XcmConfig {766 type Call = Call;767 type XcmSender = XcmRouter;768 // How to withdraw and deposit an asset.769 type AssetTransactor = LocalAssetTransactor;770 type OriginConverter = XcmOriginToTransactDispatchOrigin;771 type IsReserve = NativeAsset;772 type IsTeleporter = (); // Teleportation is disabled773 type LocationInverter = LocationInverter<Ancestry>;774 type Barrier = Barrier;775 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;776 type Trader = UsingOnlySelfCurrencyComponents<777 IdentityFee<Balance>,778 RelayLocation,779 AccountId,780 Balances,781 (),782 >;783 type ResponseHandler = (); // Don't handle responses for now.784 type SubscriptionService = PolkadotXcm;785786 type AssetTrap = PolkadotXcm;787 type AssetClaims = PolkadotXcm;788}789790// parameter_types! {791// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;792// }793794/// No local origins on this chain are allowed to dispatch XCM sends/executions.795pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);796797/// The means for routing XCM messages which are not for local execution into the right message798/// queues.799pub type XcmRouter = (800 // Two routers - use UMP to communicate with the relay chain:801 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,802 // ..and XCMP to communicate with the sibling chains.803 XcmpQueue,804);805806impl pallet_evm_coder_substrate::Config for Runtime {}807808impl pallet_xcm::Config for Runtime {809 type Event = Event;810 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;811 type XcmRouter = XcmRouter;812 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;813 type XcmExecuteFilter = Everything;814 type XcmExecutor = XcmExecutor<XcmConfig>;815 type XcmTeleportFilter = Everything;816 type XcmReserveTransferFilter = Everything;817 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;818 type LocationInverter = LocationInverter<Ancestry>;819 type Origin = Origin;820 type Call = Call;821 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;822 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;823}824825impl cumulus_pallet_xcm::Config for Runtime {826 type Event = Event;827 type XcmExecutor = XcmExecutor<XcmConfig>;828}829830impl cumulus_pallet_xcmp_queue::Config for Runtime {831 type WeightInfo = ();832 type Event = Event;833 type XcmExecutor = XcmExecutor<XcmConfig>;834 type ChannelInfo = ParachainSystem;835 type VersionWrapper = ();836 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;837 type ControllerOrigin = EnsureRoot<AccountId>;838 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;839}840841impl cumulus_pallet_dmp_queue::Config for Runtime {842 type Event = Event;843 type XcmExecutor = XcmExecutor<XcmConfig>;844 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;845}846847impl pallet_aura::Config for Runtime {848 type AuthorityId = AuraId;849 type DisabledValidators = ();850 type MaxAuthorities = MaxAuthorities;851}852853parameter_types! {854 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account();855 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;856}857858impl pallet_common::Config for Runtime {859 type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;860 type Event = Event;861 type Currency = Balances;862 type CollectionCreationPrice = CollectionCreationPrice;863 type TreasuryAccountId = TreasuryAccountId;864 type CollectionDispatch = CollectionDispatchT<Self>;865866 type EvmTokenAddressMapping = EvmTokenAddressMapping;867 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;868 type ContractAddress = EvmCollectionHelpersAddress;869}870871impl pallet_structure::Config for Runtime {872 type Event = Event;873 type Call = Call;874 type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;875}876877impl pallet_evm::account::Config for Runtime {878 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;879 type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;880 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;881}882883impl pallet_fungible::Config for Runtime {884 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;885}886impl pallet_refungible::Config for Runtime {887 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;888}889impl pallet_nonfungible::Config for Runtime {890 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;891}892/* TODO free RMRK!893impl pallet_proxy_rmrk_core::Config for Runtime {894 type Event = Event;895}896897impl pallet_proxy_rmrk_equip::Config for Runtime {898 type Event = Event;899}*/900901impl pallet_unique::Config for Runtime {902 type Event = Event;903 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;904 type CommonWeightInfo = CommonWeights<Self>;905}906907parameter_types! {908 pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied909}910911/// Used for the pallet inflation912impl pallet_inflation::Config for Runtime {913 type Currency = Balances;914 type TreasuryAccountId = TreasuryAccountId;915 type InflationBlockInterval = InflationBlockInterval;916 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;917}918919parameter_types! {920 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *921 RuntimeBlockWeights::get().max_block;922 pub const MaxScheduledPerBlock: u32 = 50;923}924925parameter_types! {926 pub const NoPreimagePostponement: Option<u32> = Some(10);927 pub const Preimage: Option<u32> = Some(10);928}929930/// Used the compare the privilege of an origin inside the scheduler.931pub struct OriginPrivilegeCmp;932impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {933 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {934 Some(Ordering::Equal)935 }936}937938impl pallet_unq_scheduler::Config for Runtime {939 type Event = Event;940 type Origin = Origin;941 type Currency = Balances;942 type PalletsOrigin = OriginCaller;943 type Call = Call;944 type MaximumWeight = MaximumSchedulerWeight;945 type ScheduleOrigin = EnsureSigned<AccountId>;946 type MaxScheduledPerBlock = MaxScheduledPerBlock;947 type WeightInfo = ();948 type CallExecutor = SchedulerPaymentExecutor;949 type OriginPrivilegeCmp = OriginPrivilegeCmp;950 type PreimageProvider = ();951 type NoPreimagePostponement = NoPreimagePostponement;952}953954type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;955use frame_support::traits::NamedReservableCurrency;956957fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {958 (959 frame_system::CheckSpecVersion::<Runtime>::new(),960 frame_system::CheckGenesis::<Runtime>::new(),961 frame_system::CheckEra::<Runtime>::from(Era::Immortal),962 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(963 from,964 )),965 frame_system::CheckWeight::<Runtime>::new(),966 // sponsoring transaction logic967 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),968 )969}970971pub struct SchedulerPaymentExecutor;972impl<T: frame_system::Config + pallet_unq_scheduler::Config, SelfContainedSignedInfo>973 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor974where975 <T as frame_system::Config>::Call: Member976 + Dispatchable<Origin = Origin, Info = DispatchInfo>977 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>978 + GetDispatchInfo979 + From<frame_system::Call<Runtime>>,980 SelfContainedSignedInfo: Send + Sync + 'static,981 Call: From<<T as frame_system::Config>::Call>982 + From<<T as pallet_unq_scheduler::Config>::Call>983 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,984 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,985{986 fn dispatch_call(987 signer: <T as frame_system::Config>::AccountId,988 call: <T as pallet_unq_scheduler::Config>::Call,989 ) -> Result<990 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,991 TransactionValidityError,992 > {993 let dispatch_info = call.get_dispatch_info();994 let extrinsic = fp_self_contained::CheckedExtrinsic::<995 AccountId,996 Call,997 SignedExtraScheduler,998 SelfContainedSignedInfo,999 > {1000 signed:1001 CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(1002 signer.clone().into(),1003 get_signed_extras(signer.into()),1004 ),1005 function: call.into(),1006 };10071008 extrinsic.apply::<Runtime>(&dispatch_info, 0)1009 }10101011 fn reserve_balance(1012 id: [u8; 16],1013 sponsor: <T as frame_system::Config>::AccountId,1014 call: <T as pallet_unq_scheduler::Config>::Call,1015 count: u32,1016 ) -> Result<(), DispatchError> {1017 let dispatch_info = call.get_dispatch_info();1018 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)1019 .saturating_mul(count.into());10201021 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(1022 &id,1023 &(sponsor.into()),1024 weight.into(),1025 )1026 }10271028 fn pay_for_call(1029 id: [u8; 16],1030 sponsor: <T as frame_system::Config>::AccountId,1031 call: <T as pallet_unq_scheduler::Config>::Call,1032 ) -> Result<u128, DispatchError> {1033 let dispatch_info = call.get_dispatch_info();1034 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);1035 Ok(1036 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(1037 &id,1038 &(sponsor.into()),1039 weight.into(),1040 ),1041 )1042 }10431044 fn cancel_reserve(1045 id: [u8; 16],1046 sponsor: <T as frame_system::Config>::AccountId,1047 ) -> Result<u128, DispatchError> {1048 Ok(1049 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(1050 &id,1051 &(sponsor.into()),1052 u128::MAX,1053 ),1054 )1055 }1056}10571058type EvmSponsorshipHandler = (1059 UniqueEthSponsorshipHandler<Runtime>,1060 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,1061);1062type SponsorshipHandler = (1063 UniqueSponsorshipHandler<Runtime>,1064 //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,1065 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,1066);10671068impl pallet_evm_transaction_payment::Config for Runtime {1069 type EvmSponsorshipHandler = EvmSponsorshipHandler;1070 type Currency = Balances;1071}10721073impl pallet_charge_transaction::Config for Runtime {1074 type SponsorshipHandler = SponsorshipHandler;1075}10761077// impl pallet_contract_helpers::Config for Runtime {1078// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;1079// }10801081parameter_types! {1082 // 0x842899ECF380553E8a4de75bF534cdf6fBF640491083 pub const HelpersContractAddress: H160 = H160([1084 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,1085 ]);1086 1087 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f1088 pub const EvmCollectionHelpersAddress: H160 = H160([1089 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,1090 ]);1091}10921093impl pallet_evm_contract_helpers::Config for Runtime {1094 type ContractAddress = HelpersContractAddress;1095 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;1096}10971098construct_runtime!(1099 pub enum Runtime where1100 Block = Block,1101 NodeBlock = opaque::Block,1102 UncheckedExtrinsic = UncheckedExtrinsic1103 {1104 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,1105 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,11061107 Aura: pallet_aura::{Pallet, Config<T>} = 22,1108 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,11091110 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,1111 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,1112 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,1113 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,1114 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,1115 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,1116 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,1117 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,1118 // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,1119 // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,11201121 // XCM helpers.1122 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,1123 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,1124 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,1125 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,11261127 // Unique Pallets1128 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,1129 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,1130 Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event<T>} = 62,1131 // free = 631132 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,1133 // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,1134 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,1135 Fungible: pallet_fungible::{Pallet, Storage} = 67,1136 Refungible: pallet_refungible::{Pallet, Storage} = 68,1137 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,1138 Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,1139 /* TODO free RMRK!1140 RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,1141 RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,*/11421143 // Frontier1144 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,1145 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,11461147 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,1148 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,1149 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,1150 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,1151 }1152);11531154pub struct TransactionConverter;11551156impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {1157 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {1158 UncheckedExtrinsic::new_unsigned(1159 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1160 )1161 }1162}11631164impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {1165 fn convert_transaction(1166 &self,1167 transaction: pallet_ethereum::Transaction,1168 ) -> opaque::UncheckedExtrinsic {1169 let extrinsic = UncheckedExtrinsic::new_unsigned(1170 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1171 );1172 let encoded = extrinsic.encode();1173 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])1174 .expect("Encoded extrinsic is always valid")1175 }1176}11771178/// The address format for describing accounts.1179pub type Address = sp_runtime::MultiAddress<AccountId, ()>;1180/// Block header type as expected by this runtime.1181pub type Header = generic::Header<BlockNumber, BlakeTwo256>;1182/// Block type as expected by this runtime.1183pub type Block = generic::Block<Header, UncheckedExtrinsic>;1184/// A Block signed with a Justification1185pub type SignedBlock = generic::SignedBlock<Block>;1186/// BlockId type as expected by this runtime.1187pub type BlockId = generic::BlockId<Block>;1188/// The SignedExtension to the basic transaction logic.1189pub type SignedExtra = (1190 frame_system::CheckSpecVersion<Runtime>,1191 // system::CheckTxVersion<Runtime>,1192 frame_system::CheckGenesis<Runtime>,1193 frame_system::CheckEra<Runtime>,1194 frame_system::CheckNonce<Runtime>,1195 frame_system::CheckWeight<Runtime>,1196 pallet_charge_transaction::ChargeTransactionPayment<Runtime>,1197 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,1198 pallet_ethereum::FakeTransactionFinalizer<Runtime>,1199);1200pub type SignedExtraScheduler = (1201 frame_system::CheckSpecVersion<Runtime>,1202 frame_system::CheckGenesis<Runtime>,1203 frame_system::CheckEra<Runtime>,1204 frame_system::CheckNonce<Runtime>,1205 frame_system::CheckWeight<Runtime>,1206 // pallet_charge_transaction::ChargeTransactionPayment<Runtime>,1207);1208/// Unchecked extrinsic type as expected by this runtime.1209pub type UncheckedExtrinsic =1210 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;1211/// Extrinsic type that has already been checked.1212pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;1213/// Executive: handles dispatch to the various modules.1214pub type Executive = frame_executive::Executive<1215 Runtime,1216 Block,1217 frame_system::ChainContext<Runtime>,1218 Runtime,1219 AllPalletsReversedWithSystemFirst,1220>;12211222impl_opaque_keys! {1223 pub struct SessionKeys {1224 pub aura: Aura,1225 }1226}12271228impl fp_self_contained::SelfContainedCall for Call {1229 type SignedInfo = H160;12301231 fn is_self_contained(&self) -> bool {1232 match self {1233 Call::Ethereum(call) => call.is_self_contained(),1234 _ => false,1235 }1236 }12371238 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {1239 match self {1240 Call::Ethereum(call) => call.check_self_contained(),1241 _ => None,1242 }1243 }12441245 fn validate_self_contained(1246 &self,1247 info: &Self::SignedInfo,1248 dispatch_info: &DispatchInfoOf<Call>,1249 len: usize,1250 ) -> Option<TransactionValidity> {1251 match self {1252 Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),1253 _ => None,1254 }1255 }12561257 fn pre_dispatch_self_contained(1258 &self,1259 info: &Self::SignedInfo,1260 ) -> Option<Result<(), TransactionValidityError>> {1261 match self {1262 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),1263 _ => None,1264 }1265 }12661267 fn apply_self_contained(1268 self,1269 info: Self::SignedInfo,1270 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {1271 match self {1272 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(1273 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),1274 )),1275 _ => None,1276 }1277 }1278}12791280macro_rules! dispatch_unique_runtime {1281 ($collection:ident.$method:ident($($name:ident),*)) => {{1282 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1283 let dispatch = collection.as_dyn();12841285 Ok::<_, DispatchError>(dispatch.$method($($name),*))1286 }};1287}12881289impl_common_runtime_apis!();12901291struct CheckInherents;12921293impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {1294 fn check_inherents(1295 block: &Block,1296 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,1297 ) -> sp_inherents::CheckInherentsResult {1298 let relay_chain_slot = relay_state_proof1299 .read_slot()1300 .expect("Could not read the relay chain slot from the proof");13011302 let inherent_data =1303 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(1304 relay_chain_slot,1305 sp_std::time::Duration::from_secs(6),1306 )1307 .create_inherent_data()1308 .expect("Could not create the timestamp inherent data");13091310 inherent_data.check_extrinsics(block)1311 }1312}13131314cumulus_pallet_parachain_system::register_validate_block!(1315 Runtime = Runtime,1316 BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,1317 CheckInherents = CheckInherents,1318);1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.1819#![cfg_attr(not(feature = "std"), no_std)]20// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.21#![recursion_limit = "1024"]22#![allow(clippy::from_over_into, clippy::identity_op)]23#![allow(clippy::fn_to_numeric_cast_with_truncation)]24// Make the WASM binary available.25#[cfg(feature = "std")]26include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));2728use sp_api::impl_runtime_apis;29use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H256, U256, H160};30use sp_runtime::DispatchError;31// #[cfg(any(feature = "std", test))]32// pub use sp_runtime::BuildStorage;3334use sp_runtime::{35 Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,36 generic::Era,37 traits::{38 Applyable, BlockNumberProvider, Dispatchable, PostDispatchInfoOf, DispatchInfoOf, Saturating,39 CheckedConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, AccountIdConversion,40 Zero, Member,41 },42 transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},43 ApplyExtrinsicResult, RuntimeAppPublic, SaturatedConversion, DispatchErrorWithPostInfo,44};4546use fp_self_contained::{SelfContainedCall, CheckedSignature};47use sp_std::{cmp::Ordering, marker::PhantomData};48use pallet_unq_scheduler::DispatchCall;4950use sp_std::prelude::*;5152#[cfg(feature = "std")]53use sp_version::NativeVersion;54use sp_version::RuntimeVersion;55pub use pallet_transaction_payment::{56 Multiplier, TargetedFeeAdjustment, FeeDetails, RuntimeDispatchInfo,57};58// A few exports that help ease life for downstream crates.59pub use pallet_balances::Call as BalancesCall;60pub use pallet_evm::{61 EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _, OnMethodCall,62 Account as EVMAccount, FeeCalculator, GasWeightMapping,63};64pub use frame_support::{65 construct_runtime, match_types,66 dispatch::DispatchResult,67 PalletId, parameter_types, StorageValue, ConsensusEngineId,68 traits::{69 tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,70 Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,71 OnUnbalanced, Randomness, FindAuthor, ConstU32, Imbalance, PrivilegeCmp,72 },73 weights::{74 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},75 DispatchClass, DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,76 WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier,77 },78};79// use pallet_contracts::weights::WeightInfo;80// #[cfg(any(feature = "std", test))]81use frame_system::{82 self as frame_system, EnsureRoot, EnsureSigned,83 limits::{BlockWeights, BlockLength},84};85use sp_arithmetic::{86 traits::{BaseArithmetic, Unsigned},87};88use smallvec::smallvec;89use codec::{Encode, Decode};90use fp_rpc::TransactionStatus;9192// pub use pallet_timestamp::Call as TimestampCall;9394// Polkadot imports95use pallet_xcm::XcmPassthrough;96use polkadot_parachain::primitives::Sibling;97use up_data_structs::{98 CollectionId, TokenId, TokenData, Property, PropertyKeyPermission, CollectionLimits, 99 CollectionStats, RpcCollection, 100 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},101 TokenChild,102};103use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};104use xcm_builder::{105 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,106 EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,107 RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,108 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,109 ParentIsPreset,110};111use xcm_executor::{Config, XcmExecutor, Assets};112113use xcm::latest::{114 // Xcm,115 AssetId::{Concrete},116 Fungibility::Fungible as XcmFungible,117 MultiAsset,118 Error as XcmError,119};120use xcm_executor::traits::{MatchesFungible, WeightTrader};121122use unique_runtime_common::{123 impl_common_runtime_apis,124 types::*,125 constants::*,126 dispatch::{CollectionDispatchT, CollectionDispatch},127 sponsoring::UniqueSponsorshipHandler,128 eth_sponsoring::UniqueEthSponsorshipHandler,129 weights::CommonWeights,130};131132pub const RUNTIME_NAME: &str = "unique";133pub const TOKEN_SYMBOL: &str = "UNQ";134135type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;136137impl RuntimeInstance for Runtime {138 type CrossAccountId = self::CrossAccountId;139140 type TransactionConverter = self::TransactionConverter;141142 fn get_transaction_converter() -> TransactionConverter {143 TransactionConverter144 }145}146147/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know148/// the specifics of the runtime. They can then be made to be agnostic over specific formats149/// of data like extrinsics, allowing for them to continue syncing the network through upgrades150/// to even the core data structures.151pub mod opaque {152 use sp_std::prelude::*;153 use sp_runtime::impl_opaque_keys;154 use super::Aura;155156 pub use unique_runtime_common::types::*;157158 impl_opaque_keys! {159 pub struct SessionKeys {160 pub aura: Aura,161 }162 }163}164165/// This runtime version.166pub const VERSION: RuntimeVersion = RuntimeVersion {167 spec_name: create_runtime_str!(RUNTIME_NAME),168 impl_name: create_runtime_str!(RUNTIME_NAME),169 authoring_version: 1,170 spec_version: 922000,171 impl_version: 0,172 apis: RUNTIME_API_VERSIONS,173 transaction_version: 1,174 state_version: 0,175};176177#[derive(codec::Encode, codec::Decode)]178pub enum XCMPMessage<XAccountId, XBalance> {179 /// Transfer tokens to the given account from the Parachain account.180 TransferToken(XAccountId, XBalance),181}182183/// The version information used to identify this runtime when compiled natively.184#[cfg(feature = "std")]185pub fn native_version() -> NativeVersion {186 NativeVersion {187 runtime_version: VERSION,188 can_author_with: Default::default(),189 }190}191192type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;193194pub struct DealWithFees;195impl OnUnbalanced<NegativeImbalance> for DealWithFees {196 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {197 if let Some(fees) = fees_then_tips.next() {198 // for fees, 100% to treasury199 let mut split = fees.ration(100, 0);200 if let Some(tips) = fees_then_tips.next() {201 // for tips, if any, 100% to treasury202 tips.ration_merge_into(100, 0, &mut split);203 }204 Treasury::on_unbalanced(split.0);205 // Author::on_unbalanced(split.1);206 }207 }208}209210parameter_types! {211 pub const BlockHashCount: BlockNumber = 2400;212 pub RuntimeBlockLength: BlockLength =213 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);214 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);215 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;216 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()217 .base_block(BlockExecutionWeight::get())218 .for_class(DispatchClass::all(), |weights| {219 weights.base_extrinsic = ExtrinsicBaseWeight::get();220 })221 .for_class(DispatchClass::Normal, |weights| {222 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);223 })224 .for_class(DispatchClass::Operational, |weights| {225 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);226 // Operational transactions have some extra reserved space, so that they227 // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.228 weights.reserved = Some(229 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT230 );231 })232 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)233 .build_or_panic();234 pub const Version: RuntimeVersion = VERSION;235 pub const SS58Prefix: u16 = 7391;236}237238parameter_types! {239 pub const ChainId: u64 = 8880;240}241242pub struct FixedFee;243impl FeeCalculator for FixedFee {244 fn min_gas_price() -> (U256, u64) {245 (MIN_GAS_PRICE.into(), 0)246 }247}248249// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case250// (contract, which only writes a lot of data),251// approximating on top of our real store write weight252parameter_types! {253 pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / <Runtime as frame_system::Config>::DbWeight::get().write;254 pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;255 pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get();256}257258/// Limiting EVM execution to 50% of block for substrate users and management tasks259/// EVM transaction consumes more weight than substrate's, so we can't rely on them being260/// scheduled fairly261const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);262parameter_types! {263 pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get());264}265266pub enum FixedGasWeightMapping {}267impl GasWeightMapping for FixedGasWeightMapping {268 fn gas_to_weight(gas: u64) -> Weight {269 gas.saturating_mul(WeightPerGas::get())270 }271 fn weight_to_gas(weight: Weight) -> u64 {272 weight / WeightPerGas::get()273 }274}275276impl pallet_evm::Config for Runtime {277 type BlockGasLimit = BlockGasLimit;278 type FeeCalculator = FixedFee;279 type GasWeightMapping = FixedGasWeightMapping;280 type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;281 type CallOrigin = EnsureAddressTruncated<Self>;282 type WithdrawOrigin = EnsureAddressTruncated<Self>;283 type AddressMapping = HashedAddressMapping<Self::Hashing>;284 type PrecompilesType = ();285 type PrecompilesValue = ();286 type Currency = Balances;287 type Event = Event;288 type OnMethodCall = (289 pallet_evm_migration::OnMethodCall<Self>,290 pallet_evm_contract_helpers::HelpersOnMethodCall<Self>,291 CollectionDispatchT<Self>,292 pallet_unique::eth::CollectionHelpersOnMethodCall<Self>,293 );294 type OnCreate = pallet_evm_contract_helpers::HelpersOnCreate<Self>;295 type ChainId = ChainId;296 type Runner = pallet_evm::runner::stack::Runner<Self>;297 type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees>;298 type TransactionValidityHack = pallet_evm_transaction_payment::TransactionValidityHack<Self>;299 type FindAuthor = EthereumFindAuthor<Aura>;300}301302impl pallet_evm_migration::Config for Runtime {303 type WeightInfo = pallet_evm_migration::weights::SubstrateWeight<Self>;304}305306pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);307impl<F: FindAuthor<u32>> FindAuthor<H160> for EthereumFindAuthor<F> {308 fn find_author<'a, I>(digests: I) -> Option<H160>309 where310 I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,311 {312 if let Some(author_index) = F::find_author(digests) {313 let authority_id = Aura::authorities()[author_index as usize].clone();314 return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24]));315 }316 None317 }318}319320impl pallet_ethereum::Config for Runtime {321 type Event = Event;322 type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;323}324325impl pallet_randomness_collective_flip::Config for Runtime {}326327impl frame_system::Config for Runtime {328 /// The data to be stored in an account.329 type AccountData = pallet_balances::AccountData<Balance>;330 /// The identifier used to distinguish between accounts.331 type AccountId = AccountId;332 /// The basic call filter to use in dispatchable.333 type BaseCallFilter = Everything;334 /// Maximum number of block number to block hash mappings to keep (oldest pruned first).335 type BlockHashCount = BlockHashCount;336 /// The maximum length of a block (in bytes).337 type BlockLength = RuntimeBlockLength;338 /// The index type for blocks.339 type BlockNumber = BlockNumber;340 /// The weight of the overhead invoked on the block import process, independent of the extrinsics included in that block.341 type BlockWeights = RuntimeBlockWeights;342 /// The aggregated dispatch type that is available for extrinsics.343 type Call = Call;344 /// The weight of database operations that the runtime can invoke.345 type DbWeight = RocksDbWeight;346 /// The ubiquitous event type.347 type Event = Event;348 /// The type for hashing blocks and tries.349 type Hash = Hash;350 /// The hashing algorithm used.351 type Hashing = BlakeTwo256;352 /// The header type.353 type Header = generic::Header<BlockNumber, BlakeTwo256>;354 /// The index type for storing how many extrinsics an account has signed.355 type Index = Index;356 /// The lookup mechanism to get account ID from whatever is passed in dispatchers.357 type Lookup = AccountIdLookup<AccountId, ()>;358 /// What to do if an account is fully reaped from the system.359 type OnKilledAccount = ();360 /// What to do if a new account is created.361 type OnNewAccount = ();362 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;363 /// The ubiquitous origin type.364 type Origin = Origin;365 /// This type is being generated by `construct_runtime!`.366 type PalletInfo = PalletInfo;367 /// This is used as an identifier of the chain. 42 is the generic substrate prefix.368 type SS58Prefix = SS58Prefix;369 /// Weight information for the extrinsics of this pallet.370 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Self>;371 /// Version of the runtime.372 type Version = Version;373 type MaxConsumers = ConstU32<16>;374}375376parameter_types! {377 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;378}379380impl pallet_timestamp::Config for Runtime {381 /// A timestamp: milliseconds since the unix epoch.382 type Moment = u64;383 type OnTimestampSet = ();384 type MinimumPeriod = MinimumPeriod;385 type WeightInfo = ();386}387388parameter_types! {389 // pub const ExistentialDeposit: u128 = 500;390 pub const ExistentialDeposit: u128 = 0;391 pub const MaxLocks: u32 = 50;392}393394impl pallet_balances::Config for Runtime {395 type MaxLocks = MaxLocks;396 type MaxReserves = ();397 type ReserveIdentifier = [u8; 16];398 /// The type for recording an account's balance.399 type Balance = Balance;400 /// The ubiquitous event type.401 type Event = Event;402 type DustRemoval = Treasury;403 type ExistentialDeposit = ExistentialDeposit;404 type AccountStore = System;405 type WeightInfo = pallet_balances::weights::SubstrateWeight<Self>;406}407408pub const fn deposit(items: u32, bytes: u32) -> Balance {409 items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE410}411412/*413parameter_types! {414 pub TombstoneDeposit: Balance = deposit(415 1,416 sp_std::mem::size_of::<pallet_contracts::Pallet<Runtime>> as u32,417 );418 pub DepositPerContract: Balance = TombstoneDeposit::get();419 pub const DepositPerStorageByte: Balance = deposit(0, 1);420 pub const DepositPerStorageItem: Balance = deposit(1, 0);421 pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);422 pub const SurchargeReward: Balance = 150 * MILLIUNIQUE;423 pub const SignedClaimHandicap: u32 = 2;424 pub const MaxDepth: u32 = 32;425 pub const MaxValueSize: u32 = 16 * 1024;426 pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb427 // The lazy deletion runs inside on_initialize.428 pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *429 RuntimeBlockWeights::get().max_block;430 // The weight needed for decoding the queue should be less or equal than a fifth431 // of the overall weight dedicated to the lazy deletion.432 pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (433 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -434 <Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)435 )) / 5) as u32;436 pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();437}438439impl pallet_contracts::Config for Runtime {440 type Time = Timestamp;441 type Randomness = RandomnessCollectiveFlip;442 type Currency = Balances;443 type Event = Event;444 type RentPayment = ();445 type SignedClaimHandicap = SignedClaimHandicap;446 type TombstoneDeposit = TombstoneDeposit;447 type DepositPerContract = DepositPerContract;448 type DepositPerStorageByte = DepositPerStorageByte;449 type DepositPerStorageItem = DepositPerStorageItem;450 type RentFraction = RentFraction;451 type SurchargeReward = SurchargeReward;452 type WeightPrice = pallet_transaction_payment::Pallet<Self>;453 type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;454 type ChainExtension = NFTExtension;455 type DeletionQueueDepth = DeletionQueueDepth;456 type DeletionWeightLimit = DeletionWeightLimit;457 type Schedule = Schedule;458 type CallStack = [pallet_contracts::Frame<Self>; 31];459}460*/461462parameter_types! {463 /// This value increases the priority of `Operational` transactions by adding464 /// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.465 pub const OperationalFeeMultiplier: u8 = 5;466}467468/// Linear implementor of `WeightToFeePolynomial`469pub struct LinearFee<T>(sp_std::marker::PhantomData<T>);470471impl<T> WeightToFeePolynomial for LinearFee<T>472where473 T: BaseArithmetic + From<u32> + Copy + Unsigned,474{475 type Balance = T;476477 fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {478 smallvec!(WeightToFeeCoefficient {479 // Targeting 0.1 Unique per NFT transfer480 coeff_integer: WEIGHT_TO_FEE_COEFF.into(),481 coeff_frac: Perbill::zero(),482 negative: false,483 degree: 1,484 })485 }486}487488impl pallet_transaction_payment::Config for Runtime {489 type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees>;490 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;491 type OperationalFeeMultiplier = OperationalFeeMultiplier;492 type WeightToFee = LinearFee<Balance>;493 type FeeMultiplierUpdate = ();494}495496parameter_types! {497 pub const ProposalBond: Permill = Permill::from_percent(5);498 pub const ProposalBondMinimum: Balance = 1 * UNIQUE;499 pub const ProposalBondMaximum: Balance = 1000 * UNIQUE;500 pub const SpendPeriod: BlockNumber = 5 * MINUTES;501 pub const Burn: Permill = Permill::from_percent(0);502 pub const TipCountdown: BlockNumber = 1 * DAYS;503 pub const TipFindersFee: Percent = Percent::from_percent(20);504 pub const TipReportDepositBase: Balance = 1 * UNIQUE;505 pub const DataDepositPerByte: Balance = 1 * CENTIUNIQUE;506 pub const BountyDepositBase: Balance = 1 * UNIQUE;507 pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;508 pub const TreasuryModuleId: PalletId = PalletId(*b"py/trsry");509 pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;510 pub const MaximumReasonLength: u32 = 16384;511 pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);512 pub const BountyValueMinimum: Balance = 5 * UNIQUE;513 pub const MaxApprovals: u32 = 100;514}515516impl pallet_treasury::Config for Runtime {517 type PalletId = TreasuryModuleId;518 type Currency = Balances;519 type ApproveOrigin = EnsureRoot<AccountId>;520 type RejectOrigin = EnsureRoot<AccountId>;521 type Event = Event;522 type OnSlash = ();523 type ProposalBond = ProposalBond;524 type ProposalBondMinimum = ProposalBondMinimum;525 type ProposalBondMaximum = ProposalBondMaximum;526 type SpendPeriod = SpendPeriod;527 type Burn = Burn;528 type BurnDestination = ();529 type SpendFunds = ();530 type WeightInfo = pallet_treasury::weights::SubstrateWeight<Self>;531 type MaxApprovals = MaxApprovals;532}533534impl pallet_sudo::Config for Runtime {535 type Event = Event;536 type Call = Call;537}538539pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);540541impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider542 for RelayChainBlockNumberProvider<T>543{544 type BlockNumber = BlockNumber;545546 fn current_block_number() -> Self::BlockNumber {547 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()548 .map(|d| d.relay_parent_number)549 .unwrap_or_default()550 }551}552553parameter_types! {554 pub const MinVestedTransfer: Balance = 10 * UNIQUE;555 pub const MaxVestingSchedules: u32 = 28;556}557558impl orml_vesting::Config for Runtime {559 type Event = Event;560 type Currency = pallet_balances::Pallet<Runtime>;561 type MinVestedTransfer = MinVestedTransfer;562 type VestedTransferOrigin = EnsureSigned<AccountId>;563 type WeightInfo = ();564 type MaxVestingSchedules = MaxVestingSchedules;565 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;566}567568parameter_types! {569 pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;570 pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;571}572573impl cumulus_pallet_parachain_system::Config for Runtime {574 type Event = Event;575 type SelfParaId = parachain_info::Pallet<Self>;576 type OnSystemEvent = ();577 // type DownwardMessageHandlers = cumulus_primitives_utility::UnqueuedDmpAsParent<578 // MaxDownwardMessageWeight,579 // XcmExecutor<XcmConfig>,580 // Call,581 // >;582 type OutboundXcmpMessageSource = XcmpQueue;583 type DmpMessageHandler = DmpQueue;584 type ReservedDmpWeight = ReservedDmpWeight;585 type ReservedXcmpWeight = ReservedXcmpWeight;586 type XcmpMessageHandler = XcmpQueue;587}588589impl parachain_info::Config for Runtime {}590591impl cumulus_pallet_aura_ext::Config for Runtime {}592593parameter_types! {594 pub const RelayLocation: MultiLocation = MultiLocation::parent();595 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;596 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();597 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();598}599600/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used601/// when determining ownership of accounts for asset transacting and when attempting to use XCM602/// `Transact` in order to determine the dispatch Origin.603pub type LocationToAccountId = (604 // The parent (Relay-chain) origin converts to the default `AccountId`.605 ParentIsPreset<AccountId>,606 // Sibling parachain origins convert to AccountId via the `ParaId::into`.607 SiblingParachainConvertsVia<Sibling, AccountId>,608 // Straight up local `AccountId32` origins just alias directly to `AccountId`.609 AccountId32Aliases<RelayNetwork, AccountId>,610);611612pub struct OnlySelfCurrency;613impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {614 fn matches_fungible(a: &MultiAsset) -> Option<B> {615 match (&a.id, &a.fun) {616 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),617 _ => None,618 }619 }620}621622/// Means for transacting assets on this chain.623pub type LocalAssetTransactor = CurrencyAdapter<624 // Use this currency:625 Balances,626 // Use this currency when it is a fungible asset matching the given location or name:627 OnlySelfCurrency,628 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:629 LocationToAccountId,630 // Our chain's account ID type (we can't get away without mentioning it explicitly):631 AccountId,632 // We don't track any teleports.633 (),634>;635636/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,637/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can638/// biases the kind of local `Origin` it will become.639pub type XcmOriginToTransactDispatchOrigin = (640 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location641 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for642 // foreign chains who want to have a local sovereign account on this chain which they control.643 SovereignSignedViaLocation<LocationToAccountId, Origin>,644 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when645 // recognised.646 RelayChainAsNative<RelayOrigin, Origin>,647 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when648 // recognised.649 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,650 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a651 // transaction from the Root origin.652 ParentAsSuperuser<Origin>,653 // Native signed account converter; this just converts an `AccountId32` origin into a normal654 // `Origin::Signed` origin of the same 32-byte value.655 SignedAccountId32AsNative<RelayNetwork, Origin>,656 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.657 XcmPassthrough<Origin>,658);659660parameter_types! {661 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.662 pub UnitWeightCost: Weight = 1_000_000;663 // 1200 UNIQUEs buy 1 second of weight.664 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);665 pub const MaxInstructions: u32 = 100;666 pub const MaxAuthorities: u32 = 100_000;667}668669match_types! {670 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {671 MultiLocation { parents: 1, interior: Here } |672 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }673 };674}675676pub type Barrier = (677 TakeWeightCredit,678 AllowTopLevelPaidExecutionFrom<Everything>,679 AllowUnpaidExecutionFrom<ParentOrParentsUnitPlurality>,680 // ^^^ Parent & its unit plurality gets free execution681);682683pub struct UsingOnlySelfCurrencyComponents<684 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,685 AssetId: Get<MultiLocation>,686 AccountId,687 Currency: CurrencyT<AccountId>,688 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,689>(690 Weight,691 Currency::Balance,692 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,693);694impl<695 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,696 AssetId: Get<MultiLocation>,697 AccountId,698 Currency: CurrencyT<AccountId>,699 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,700 > WeightTrader701 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>702{703 fn new() -> Self {704 Self(0, Zero::zero(), PhantomData)705 }706707 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {708 let amount = WeightToFee::calc(&weight);709 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;710711 // location to this parachain through relay chain712 let option1: xcm::v1::AssetId = Concrete(MultiLocation {713 parents: 1,714 interior: X1(Parachain(ParachainInfo::parachain_id().into())),715 });716 // direct location717 let option2: xcm::v1::AssetId = Concrete(MultiLocation {718 parents: 0,719 interior: Here,720 });721722 let required = if payment.fungible.contains_key(&option1) {723 (option1, u128_amount).into()724 } else if payment.fungible.contains_key(&option2) {725 (option2, u128_amount).into()726 } else {727 (Concrete(MultiLocation::default()), u128_amount).into()728 };729730 let unused = payment731 .checked_sub(required)732 .map_err(|_| XcmError::TooExpensive)?;733 self.0 = self.0.saturating_add(weight);734 self.1 = self.1.saturating_add(amount);735 Ok(unused)736 }737738 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {739 let weight = weight.min(self.0);740 let amount = WeightToFee::calc(&weight);741 self.0 -= weight;742 self.1 = self.1.saturating_sub(amount);743 let amount: u128 = amount.saturated_into();744 if amount > 0 {745 Some((AssetId::get(), amount).into())746 } else {747 None748 }749 }750}751impl<752 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,753 AssetId: Get<MultiLocation>,754 AccountId,755 Currency: CurrencyT<AccountId>,756 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,757 > Drop758 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>759{760 fn drop(&mut self) {761 OnUnbalanced::on_unbalanced(Currency::issue(self.1));762 }763}764765pub struct XcmConfig;766impl Config for XcmConfig {767 type Call = Call;768 type XcmSender = XcmRouter;769 // How to withdraw and deposit an asset.770 type AssetTransactor = LocalAssetTransactor;771 type OriginConverter = XcmOriginToTransactDispatchOrigin;772 type IsReserve = NativeAsset;773 type IsTeleporter = (); // Teleportation is disabled774 type LocationInverter = LocationInverter<Ancestry>;775 type Barrier = Barrier;776 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;777 type Trader = UsingOnlySelfCurrencyComponents<778 IdentityFee<Balance>,779 RelayLocation,780 AccountId,781 Balances,782 (),783 >;784 type ResponseHandler = (); // Don't handle responses for now.785 type SubscriptionService = PolkadotXcm;786787 type AssetTrap = PolkadotXcm;788 type AssetClaims = PolkadotXcm;789}790791// parameter_types! {792// pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;793// }794795/// No local origins on this chain are allowed to dispatch XCM sends/executions.796pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);797798/// The means for routing XCM messages which are not for local execution into the right message799/// queues.800pub type XcmRouter = (801 // Two routers - use UMP to communicate with the relay chain:802 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,803 // ..and XCMP to communicate with the sibling chains.804 XcmpQueue,805);806807impl pallet_evm_coder_substrate::Config for Runtime {}808809impl pallet_xcm::Config for Runtime {810 type Event = Event;811 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;812 type XcmRouter = XcmRouter;813 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;814 type XcmExecuteFilter = Everything;815 type XcmExecutor = XcmExecutor<XcmConfig>;816 type XcmTeleportFilter = Everything;817 type XcmReserveTransferFilter = Everything;818 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;819 type LocationInverter = LocationInverter<Ancestry>;820 type Origin = Origin;821 type Call = Call;822 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;823 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;824}825826impl cumulus_pallet_xcm::Config for Runtime {827 type Event = Event;828 type XcmExecutor = XcmExecutor<XcmConfig>;829}830831impl cumulus_pallet_xcmp_queue::Config for Runtime {832 type WeightInfo = ();833 type Event = Event;834 type XcmExecutor = XcmExecutor<XcmConfig>;835 type ChannelInfo = ParachainSystem;836 type VersionWrapper = ();837 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;838 type ControllerOrigin = EnsureRoot<AccountId>;839 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;840}841842impl cumulus_pallet_dmp_queue::Config for Runtime {843 type Event = Event;844 type XcmExecutor = XcmExecutor<XcmConfig>;845 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;846}847848impl pallet_aura::Config for Runtime {849 type AuthorityId = AuraId;850 type DisabledValidators = ();851 type MaxAuthorities = MaxAuthorities;852}853854parameter_types! {855 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account();856 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;857}858859impl pallet_common::Config for Runtime {860 type WeightInfo = pallet_common::weights::SubstrateWeight<Self>;861 type Event = Event;862 type Currency = Balances;863 type CollectionCreationPrice = CollectionCreationPrice;864 type TreasuryAccountId = TreasuryAccountId;865 type CollectionDispatch = CollectionDispatchT<Self>;866867 type EvmTokenAddressMapping = EvmTokenAddressMapping;868 type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;869 type ContractAddress = EvmCollectionHelpersAddress;870}871872impl pallet_structure::Config for Runtime {873 type Event = Event;874 type Call = Call;875 type WeightInfo = pallet_structure::weights::SubstrateWeight<Self>;876}877878impl pallet_evm::account::Config for Runtime {879 type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Self>;880 type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;881 type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;882}883884impl pallet_fungible::Config for Runtime {885 type WeightInfo = pallet_fungible::weights::SubstrateWeight<Self>;886}887impl pallet_refungible::Config for Runtime {888 type WeightInfo = pallet_refungible::weights::SubstrateWeight<Self>;889}890impl pallet_nonfungible::Config for Runtime {891 type WeightInfo = pallet_nonfungible::weights::SubstrateWeight<Self>;892}893/* TODO free RMRK!894impl pallet_proxy_rmrk_core::Config for Runtime {895 type Event = Event;896}897898impl pallet_proxy_rmrk_equip::Config for Runtime {899 type Event = Event;900}*/901902impl pallet_unique::Config for Runtime {903 type Event = Event;904 type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;905 type CommonWeightInfo = CommonWeights<Self>;906}907908parameter_types! {909 pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied910}911912/// Used for the pallet inflation913impl pallet_inflation::Config for Runtime {914 type Currency = Balances;915 type TreasuryAccountId = TreasuryAccountId;916 type InflationBlockInterval = InflationBlockInterval;917 type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;918}919920parameter_types! {921 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *922 RuntimeBlockWeights::get().max_block;923 pub const MaxScheduledPerBlock: u32 = 50;924}925926parameter_types! {927 pub const NoPreimagePostponement: Option<u32> = Some(10);928 pub const Preimage: Option<u32> = Some(10);929}930931/// Used the compare the privilege of an origin inside the scheduler.932pub struct OriginPrivilegeCmp;933impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {934 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {935 Some(Ordering::Equal)936 }937}938939impl pallet_unq_scheduler::Config for Runtime {940 type Event = Event;941 type Origin = Origin;942 type Currency = Balances;943 type PalletsOrigin = OriginCaller;944 type Call = Call;945 type MaximumWeight = MaximumSchedulerWeight;946 type ScheduleOrigin = EnsureSigned<AccountId>;947 type MaxScheduledPerBlock = MaxScheduledPerBlock;948 type WeightInfo = ();949 type CallExecutor = SchedulerPaymentExecutor;950 type OriginPrivilegeCmp = OriginPrivilegeCmp;951 type PreimageProvider = ();952 type NoPreimagePostponement = NoPreimagePostponement;953}954955type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;956use frame_support::traits::NamedReservableCurrency;957958fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {959 (960 frame_system::CheckSpecVersion::<Runtime>::new(),961 frame_system::CheckGenesis::<Runtime>::new(),962 frame_system::CheckEra::<Runtime>::from(Era::Immortal),963 frame_system::CheckNonce::<Runtime>::from(frame_system::Pallet::<Runtime>::account_nonce(964 from,965 )),966 frame_system::CheckWeight::<Runtime>::new(),967 // sponsoring transaction logic968 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),969 )970}971972pub struct SchedulerPaymentExecutor;973impl<T: frame_system::Config + pallet_unq_scheduler::Config, SelfContainedSignedInfo>974 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor975where976 <T as frame_system::Config>::Call: Member977 + Dispatchable<Origin = Origin, Info = DispatchInfo>978 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>979 + GetDispatchInfo980 + From<frame_system::Call<Runtime>>,981 SelfContainedSignedInfo: Send + Sync + 'static,982 Call: From<<T as frame_system::Config>::Call>983 + From<<T as pallet_unq_scheduler::Config>::Call>984 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,985 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,986{987 fn dispatch_call(988 signer: <T as frame_system::Config>::AccountId,989 call: <T as pallet_unq_scheduler::Config>::Call,990 ) -> Result<991 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,992 TransactionValidityError,993 > {994 let dispatch_info = call.get_dispatch_info();995 let extrinsic = fp_self_contained::CheckedExtrinsic::<996 AccountId,997 Call,998 SignedExtraScheduler,999 SelfContainedSignedInfo,1000 > {1001 signed:1002 CheckedSignature::<AccountId, SignedExtraScheduler, SelfContainedSignedInfo>::Signed(1003 signer.clone().into(),1004 get_signed_extras(signer.into()),1005 ),1006 function: call.into(),1007 };10081009 extrinsic.apply::<Runtime>(&dispatch_info, 0)1010 }10111012 fn reserve_balance(1013 id: [u8; 16],1014 sponsor: <T as frame_system::Config>::AccountId,1015 call: <T as pallet_unq_scheduler::Config>::Call,1016 count: u32,1017 ) -> Result<(), DispatchError> {1018 let dispatch_info = call.get_dispatch_info();1019 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)1020 .saturating_mul(count.into());10211022 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(1023 &id,1024 &(sponsor.into()),1025 weight.into(),1026 )1027 }10281029 fn pay_for_call(1030 id: [u8; 16],1031 sponsor: <T as frame_system::Config>::AccountId,1032 call: <T as pallet_unq_scheduler::Config>::Call,1033 ) -> Result<u128, DispatchError> {1034 let dispatch_info = call.get_dispatch_info();1035 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);1036 Ok(1037 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(1038 &id,1039 &(sponsor.into()),1040 weight.into(),1041 ),1042 )1043 }10441045 fn cancel_reserve(1046 id: [u8; 16],1047 sponsor: <T as frame_system::Config>::AccountId,1048 ) -> Result<u128, DispatchError> {1049 Ok(1050 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(1051 &id,1052 &(sponsor.into()),1053 u128::MAX,1054 ),1055 )1056 }1057}10581059type EvmSponsorshipHandler = (1060 UniqueEthSponsorshipHandler<Runtime>,1061 pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,1062);1063type SponsorshipHandler = (1064 UniqueSponsorshipHandler<Runtime>,1065 //pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,1066 pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,1067);10681069impl pallet_evm_transaction_payment::Config for Runtime {1070 type EvmSponsorshipHandler = EvmSponsorshipHandler;1071 type Currency = Balances;1072}10731074impl pallet_charge_transaction::Config for Runtime {1075 type SponsorshipHandler = SponsorshipHandler;1076}10771078// impl pallet_contract_helpers::Config for Runtime {1079// type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;1080// }10811082parameter_types! {1083 // 0x842899ECF380553E8a4de75bF534cdf6fBF640491084 pub const HelpersContractAddress: H160 = H160([1085 0x84, 0x28, 0x99, 0xec, 0xf3, 0x80, 0x55, 0x3e, 0x8a, 0x4d, 0xe7, 0x5b, 0xf5, 0x34, 0xcd, 0xf6, 0xfb, 0xf6, 0x40, 0x49,1086 ]);1087 1088 // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f1089 pub const EvmCollectionHelpersAddress: H160 = H160([1090 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,1091 ]);1092}10931094impl pallet_evm_contract_helpers::Config for Runtime {1095 type ContractAddress = HelpersContractAddress;1096 type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;1097}10981099construct_runtime!(1100 pub enum Runtime where1101 Block = Block,1102 NodeBlock = opaque::Block,1103 UncheckedExtrinsic = UncheckedExtrinsic1104 {1105 ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,1106 ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,11071108 Aura: pallet_aura::{Pallet, Config<T>} = 22,1109 AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 23,11101111 Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 30,1112 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 31,1113 Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 32,1114 TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 33,1115 Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 34,1116 Sudo: pallet_sudo::{Pallet, Call, Storage, Config<T>, Event<T>} = 35,1117 System: frame_system::{Pallet, Call, Storage, Config, Event<T>} = 36,1118 Vesting: orml_vesting::{Pallet, Storage, Call, Event<T>, Config<T>} = 37,1119 // Vesting: pallet_vesting::{Pallet, Call, Config<T>, Storage, Event<T>} = 37,1120 // Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 38,11211122 // XCM helpers.1123 XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 50,1124 PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin} = 51,1125 CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event<T>, Origin} = 52,1126 DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 53,11271128 // Unique Pallets1129 Inflation: pallet_inflation::{Pallet, Call, Storage} = 60,1130 Unique: pallet_unique::{Pallet, Call, Storage, Event<T>} = 61,1131 Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event<T>} = 62,1132 // free = 631133 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64,1134 // ContractHelpers: pallet_contract_helpers::{Pallet, Call, Storage} = 65,1135 Common: pallet_common::{Pallet, Storage, Event<T>} = 66,1136 Fungible: pallet_fungible::{Pallet, Storage} = 67,1137 Refungible: pallet_refungible::{Pallet, Storage} = 68,1138 Nonfungible: pallet_nonfungible::{Pallet, Storage} = 69,1139 Structure: pallet_structure::{Pallet, Call, Storage, Event<T>} = 70,1140 /* TODO free RMRK!1141 RmrkCore: pallet_proxy_rmrk_core::{Pallet, Call, Storage, Event<T>} = 71,1142 RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event<T>} = 72,*/11431144 // Frontier1145 EVM: pallet_evm::{Pallet, Config, Call, Storage, Event<T>} = 100,1146 Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,11471148 EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,1149 EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,1150 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,1151 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,1152 }1153);11541155pub struct TransactionConverter;11561157impl fp_rpc::ConvertTransaction<UncheckedExtrinsic> for TransactionConverter {1158 fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic {1159 UncheckedExtrinsic::new_unsigned(1160 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1161 )1162 }1163}11641165impl fp_rpc::ConvertTransaction<opaque::UncheckedExtrinsic> for TransactionConverter {1166 fn convert_transaction(1167 &self,1168 transaction: pallet_ethereum::Transaction,1169 ) -> opaque::UncheckedExtrinsic {1170 let extrinsic = UncheckedExtrinsic::new_unsigned(1171 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),1172 );1173 let encoded = extrinsic.encode();1174 opaque::UncheckedExtrinsic::decode(&mut &encoded[..])1175 .expect("Encoded extrinsic is always valid")1176 }1177}11781179/// The address format for describing accounts.1180pub type Address = sp_runtime::MultiAddress<AccountId, ()>;1181/// Block header type as expected by this runtime.1182pub type Header = generic::Header<BlockNumber, BlakeTwo256>;1183/// Block type as expected by this runtime.1184pub type Block = generic::Block<Header, UncheckedExtrinsic>;1185/// A Block signed with a Justification1186pub type SignedBlock = generic::SignedBlock<Block>;1187/// BlockId type as expected by this runtime.1188pub type BlockId = generic::BlockId<Block>;1189/// The SignedExtension to the basic transaction logic.1190pub type SignedExtra = (1191 frame_system::CheckSpecVersion<Runtime>,1192 // system::CheckTxVersion<Runtime>,1193 frame_system::CheckGenesis<Runtime>,1194 frame_system::CheckEra<Runtime>,1195 frame_system::CheckNonce<Runtime>,1196 frame_system::CheckWeight<Runtime>,1197 pallet_charge_transaction::ChargeTransactionPayment<Runtime>,1198 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,1199 pallet_ethereum::FakeTransactionFinalizer<Runtime>,1200);1201pub type SignedExtraScheduler = (1202 frame_system::CheckSpecVersion<Runtime>,1203 frame_system::CheckGenesis<Runtime>,1204 frame_system::CheckEra<Runtime>,1205 frame_system::CheckNonce<Runtime>,1206 frame_system::CheckWeight<Runtime>,1207 // pallet_charge_transaction::ChargeTransactionPayment<Runtime>,1208);1209/// Unchecked extrinsic type as expected by this runtime.1210pub type UncheckedExtrinsic =1211 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;1212/// Extrinsic type that has already been checked.1213pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;1214/// Executive: handles dispatch to the various modules.1215pub type Executive = frame_executive::Executive<1216 Runtime,1217 Block,1218 frame_system::ChainContext<Runtime>,1219 Runtime,1220 AllPalletsReversedWithSystemFirst,1221>;12221223impl_opaque_keys! {1224 pub struct SessionKeys {1225 pub aura: Aura,1226 }1227}12281229impl fp_self_contained::SelfContainedCall for Call {1230 type SignedInfo = H160;12311232 fn is_self_contained(&self) -> bool {1233 match self {1234 Call::Ethereum(call) => call.is_self_contained(),1235 _ => false,1236 }1237 }12381239 fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {1240 match self {1241 Call::Ethereum(call) => call.check_self_contained(),1242 _ => None,1243 }1244 }12451246 fn validate_self_contained(1247 &self,1248 info: &Self::SignedInfo,1249 dispatch_info: &DispatchInfoOf<Call>,1250 len: usize,1251 ) -> Option<TransactionValidity> {1252 match self {1253 Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),1254 _ => None,1255 }1256 }12571258 fn pre_dispatch_self_contained(1259 &self,1260 info: &Self::SignedInfo,1261 ) -> Option<Result<(), TransactionValidityError>> {1262 match self {1263 Call::Ethereum(call) => call.pre_dispatch_self_contained(info),1264 _ => None,1265 }1266 }12671268 fn apply_self_contained(1269 self,1270 info: Self::SignedInfo,1271 ) -> Option<sp_runtime::DispatchResultWithInfo<PostDispatchInfoOf<Self>>> {1272 match self {1273 call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(1274 Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)),1275 )),1276 _ => None,1277 }1278 }1279}12801281macro_rules! dispatch_unique_runtime {1282 ($collection:ident.$method:ident($($name:ident),*)) => {{1283 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1284 let dispatch = collection.as_dyn();12851286 Ok::<_, DispatchError>(dispatch.$method($($name),*))1287 }};1288}12891290impl_common_runtime_apis!();12911292struct CheckInherents;12931294impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {1295 fn check_inherents(1296 block: &Block,1297 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,1298 ) -> sp_inherents::CheckInherentsResult {1299 let relay_chain_slot = relay_state_proof1300 .read_slot()1301 .expect("Could not read the relay chain slot from the proof");13021303 let inherent_data =1304 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(1305 relay_chain_slot,1306 sp_std::time::Duration::from_secs(6),1307 )1308 .create_inherent_data()1309 .expect("Could not create the timestamp inherent data");13101311 inherent_data.check_extrinsics(block)1312 }1313}13141315cumulus_pallet_parachain_system::register_validate_block!(1316 Runtime = Runtime,1317 BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,1318 CheckInherents = CheckInherents,1319);