difftreelog
feat initial rmrk send impl
in: master
10 files changed
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -1298,6 +1298,7 @@
spender: T::CrossAccountId,
token: TokenId,
amount: u128,
+ nesting_budget: &dyn Budget,
) -> DispatchResultWithPostInfo;
fn transfer_from(
&self,
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -226,6 +226,7 @@
spender: T::CrossAccountId,
token: TokenId,
amount: u128,
+ _nesting_budget: &dyn Budget,
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -308,14 +308,15 @@
spender: T::CrossAccountId,
token: TokenId,
amount: u128,
+ nesting_budget: &dyn Budget,
) -> DispatchResultWithPostInfo {
ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);
with_weight(
if amount == 1 {
- <Pallet<T>>::set_allowance(self, &sender, token, Some(&spender))
+ <Pallet<T>>::set_allowance(self, &sender, token, Some(&spender), nesting_budget)
} else {
- <Pallet<T>>::set_allowance(self, &sender, token, None)
+ <Pallet<T>>::set_allowance(self, &sender, token, None, nesting_budget)
},
<CommonWeights<T>>::approve(),
)
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -269,8 +269,11 @@
let caller = T::CrossAccountId::from_eth(caller);
let approved = T::CrossAccountId::from_eth(approved);
let token = token_id.try_into()?;
+ let budget = self
+ .recorder
+ .weight_calls_budget(<StructureWeight<T>>::find_parent());
- <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved))
+ <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved), &budget)
.map_err(dispatch_to_evm::<T>)?;
Ok(())
}
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -878,6 +878,7 @@
sender: &T::CrossAccountId,
token: TokenId,
spender: Option<&T::CrossAccountId>,
+ nesting_budget: &dyn Budget,
) -> DispatchResult {
if collection.permissions.access() == AccessMode::AllowList {
collection.check_allowlist(sender)?;
@@ -889,9 +890,16 @@
if let Some(spender) = spender {
<PalletCommon<T>>::ensure_correct_receiver(spender)?;
}
- let token_data =
- <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;
- if &token_data.owner != sender {
+
+ let is_owned = <PalletStructure<T>>::check_indirectly_owned(
+ sender.clone(),
+ collection.id,
+ token,
+ None,
+ nesting_budget
+ )?;
+
+ if !is_owned {
ensure!(
collection.ignores_owned_amount(sender),
<CommonError<T>>::CantApproveMoreThanOwned
@@ -918,6 +926,9 @@
// `from`, `to` checked in [`transfer`]
collection.check_allowlist(spender)?;
}
+ if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {
+ return Ok(());
+ }
if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
// TODO: should collection owner be allowed to perform this transfer?
ensure!(
@@ -930,9 +941,6 @@
)?,
<CommonError<T>>::ApprovedValueTooLow,
);
- return Ok(());
- }
- if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {
return Ok(());
}
ensure!(
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/lib.rs
+++ b/pallets/proxy-rmrk-core/src/lib.rs
@@ -20,7 +20,7 @@
use frame_system::{pallet_prelude::*, ensure_signed};
use sp_runtime::{DispatchError, Permill, traits::StaticLookup};
use sp_std::vec::Vec;
-use up_data_structs::*;
+use up_data_structs::{*, mapping::TokenAddressMapping};
use pallet_common::{
Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,
};
@@ -39,6 +39,8 @@
use RmrkProperty::*;
+const NESTING_BUDGET: u32 = 5;
+
#[frame_support::pallet]
pub mod pallet {
use super::*;
@@ -56,10 +58,13 @@
pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;
#[pallet::storage]
- #[pallet::getter(fn collection_index_map)]
- pub type CollectionIndexMap<T: Config> =
+ pub type UniqueCollectionId<T: Config> =
StorageMap<_, Twox64Concat, RmrkCollectionId, CollectionId, ValueQuery>;
+ #[pallet::storage]
+ pub type RmrkInernalCollectionId<T: Config> =
+ StorageMap<_, Twox64Concat, CollectionId, RmrkCollectionId, ValueQuery>;
+
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
@@ -151,10 +156,12 @@
.into_inner()
.try_into()
.map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
+ permissions: Some(CollectionPermissions {
+ nesting: Some(NestingRule::Owner),
+ ..Default::default()
+ }),
..Default::default()
};
-
- <CollectionIndex<T>>::mutate(|n| *n += 1);
let unique_collection_id = Self::init_collection(
T::CrossAccountId::from_sub(sender.clone()),
@@ -167,7 +174,10 @@
)?;
let rmrk_collection_id = <CollectionIndex<T>>::get();
- <CollectionIndexMap<T>>::insert(rmrk_collection_id, unique_collection_id);
+ <UniqueCollectionId<T>>::insert(rmrk_collection_id, unique_collection_id);
+ <RmrkInernalCollectionId<T>>::insert(unique_collection_id, rmrk_collection_id);
+
+ <CollectionIndex<T>>::mutate(|n| *n += 1);
Self::deposit_event(Event::CollectionCreated {
issuer: sender,
@@ -356,6 +366,81 @@
#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
#[transactional]
+ pub fn send(
+ origin: OriginFor<T>,
+ rmrk_collection_id: RmrkCollectionId,
+ rmrk_nft_id: RmrkNftId,
+ new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,
+ ) -> DispatchResult {
+ let sender = ensure_signed(origin.clone())?;
+ let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+
+ let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+ let nft_id = rmrk_nft_id.into();
+
+ let token_data = <TokenData<T>>::get((collection_id, nft_id))
+ .ok_or(<Error<T>>::NoAvailableNftId)?;
+
+ let from = token_data.owner;
+
+ let collection = Self::get_typed_nft_collection(
+ collection_id,
+ misc::CollectionType::Regular,
+ )?;
+
+ let budget = budget::Value::new(NESTING_BUDGET);
+
+ let target_owner;
+
+ match new_owner {
+ RmrkAccountIdOrCollectionNftTuple::AccountId(account_id) => {
+ target_owner = T::CrossAccountId::from_sub(account_id);
+ },
+ RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(target_collection_id, target_nft_id) => {
+ let target_collection_id = Self::unique_collection_id(target_collection_id)?;
+
+ target_owner = T::CrossTokenAddressMapping::token_to_address(
+ target_collection_id,
+ target_nft_id.into(),
+ );
+
+ let spender = <PalletStructure<T>>::get_indirect_owner(
+ target_collection_id,
+ target_nft_id.into(),
+ Some((collection_id, nft_id)),
+ &budget,
+ )?;
+
+ let is_approval_required = cross_sender != spender;
+
+ if is_approval_required {
+ <PalletNft<T>>::set_allowance(
+ &collection,
+ &cross_sender,
+ nft_id,
+ Some(&spender),
+ &budget
+ ).map_err(Self::map_common_err_to_proxy)?;
+
+ return Ok(());
+ }
+ }
+ }
+
+ <PalletNft<T>>::transfer_from(
+ &collection,
+ &cross_sender,
+ &from,
+ &target_owner,
+ nft_id,
+ &budget
+ ).map_err(Self::map_common_err_to_proxy)?;
+
+ Ok(())
+ }
+
+ #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+ #[transactional]
pub fn set_property(
origin: OriginFor<T>,
#[pallet::compact] rmrk_collection_id: RmrkCollectionId,
@@ -367,12 +452,13 @@
let sender = T::CrossAccountId::from_sub(sender);
let collection_id = Self::unique_collection_id(rmrk_collection_id)?;
+ let budget = budget::Value::new(NESTING_BUDGET);
match maybe_nft_id {
Some(nft_id) => {
let token_id: TokenId = nft_id.into();
- Self::ensure_nft_owner(collection_id, token_id, &sender)?;
+ Self::ensure_nft_owner(collection_id, token_id, &sender, &budget)?;
Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;
<PalletNft<T>>::set_scoped_token_property(
@@ -607,7 +693,7 @@
owner: owner.clone(),
};
- let budget = budget::Value::new(2);
+ let budget = budget::Value::new(NESTING_BUDGET);
<PalletNft<T>>::create_item(collection, sender, data, &budget)?;
@@ -651,14 +737,8 @@
//ensure!(!Pallet::<T>::is_locked(collection_id, nft_id), pallet_uniques::Error::<T>::Locked);
let sender = T::CrossAccountId::from_sub(sender);
- let budget = budget::Value::new(10);
- let pending = !<PalletStructure<T>>::check_indirectly_owned(
- sender.clone(),
- collection_id,
- token_id,
- None,
- &budget,
- )?;
+ let budget = budget::Value::new(NESTING_BUDGET);
+ let pending = Self::ensure_nft_owner(collection_id, token_id, &sender, &budget).is_err();
let resource_collection_id: CollectionId =
Self::get_nft_property_decoded(collection_id, token_id, ResourceCollection)?;
@@ -757,7 +837,14 @@
pub fn unique_collection_id(
rmrk_collection_id: RmrkCollectionId,
) -> Result<CollectionId, DispatchError> {
- <CollectionIndexMap<T>>::try_get(rmrk_collection_id)
+ <UniqueCollectionId<T>>::try_get(rmrk_collection_id)
+ .map_err(|_| <Error<T>>::CollectionUnknown.into())
+ }
+
+ pub fn rmrk_collection_id(
+ unique_collection_id: CollectionId
+ ) -> Result<RmrkCollectionId, DispatchError> {
+ <RmrkInernalCollectionId<T>>::try_get(unique_collection_id)
.map_err(|_| <Error<T>>::CollectionUnknown.into())
}
@@ -873,12 +960,18 @@
collection_id: CollectionId,
token_id: TokenId,
possible_owner: &T::CrossAccountId,
+ nesting_budget: &dyn budget::Budget
) -> DispatchResult {
- let token_data =
- <TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;
+ let is_owned = <PalletStructure<T>>::check_indirectly_owned(
+ possible_owner.clone(),
+ collection_id,
+ token_id,
+ None,
+ nesting_budget,
+ )?;
ensure!(
- token_data.owner == *possible_owner,
+ is_owned,
<Error<T>>::NoPermission
);
@@ -965,7 +1058,8 @@
NoPermission => NoPermission,
CollectionTokenLimitExceeded => CollectionFullOrLocked,
PublicMintingNotAllowed => NoPermission,
- TokenNotFound => NoAvailableNftId
+ TokenNotFound => NoAvailableNftId,
+ ApprovedValueTooLow => NoPermission
}
}
}
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -254,6 +254,7 @@
spender: T::CrossAccountId,
token: TokenId,
amount: u128,
+ _nesting_budget: &dyn Budget,
) -> DispatchResultWithPostInfo {
with_weight(
<Pallet<T>>::set_allowance(self, &sender, &spender, token, amount),
pallets/structure/src/lib.rsdiffbeforeafterboth--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -149,19 +149,12 @@
})
}
- /// Check if token indirectly owned by specified user
- pub fn check_indirectly_owned(
- user: T::CrossAccountId,
+ pub fn get_indirect_owner(
collection: CollectionId,
token: TokenId,
for_nest: Option<(CollectionId, TokenId)>,
budget: &dyn Budget,
- ) -> Result<bool, DispatchError> {
- let target_parent = match T::CrossTokenAddressMapping::address_to_token(&user) {
- Some((collection, token)) => Self::find_topmost_owner(collection, token, budget)?,
- None => user,
- };
-
+ ) -> Result<T::CrossAccountId, DispatchError> {
// Tried to nest token in itself
if Some((collection, token)) == for_nest {
return Err(<Error<T>>::OuroborosDetected.into());
@@ -173,10 +166,8 @@
Parent::Token(collection, token) if Some((collection, token)) == for_nest => {
return Err(<Error<T>>::OuroborosDetected.into())
}
- // Found needed parent, token is indirecty owned
- Parent::User(user) if user == target_parent => return Ok(true),
// Token is owned by other user
- Parent::User(_) => return Ok(false),
+ Parent::User(user) => return Ok(user),
Parent::TokenNotFound => return Err(<Error<T>>::TokenNotFound.into()),
// Continue parent chain
Parent::Token(_, _) => {}
@@ -199,6 +190,27 @@
dispatch.burn_item_recursively(from.clone(), token, self_budget, breadth_budget)
}
+ /// Check if token indirectly owned by specified user
+ pub fn check_indirectly_owned(
+ user: T::CrossAccountId,
+ collection: CollectionId,
+ token: TokenId,
+ for_nest: Option<(CollectionId, TokenId)>,
+ budget: &dyn Budget,
+ ) -> Result<bool, DispatchError> {
+ let target_parent = match T::CrossTokenAddressMapping::address_to_token(&user) {
+ Some((collection, token)) => Self::find_topmost_owner(collection, token, budget)?,
+ None => user,
+ };
+
+ Self::get_indirect_owner(
+ collection,
+ token,
+ for_nest,
+ budget
+ ).map(|indirect_owner| indirect_owner == target_parent)
+ }
+
pub fn check_nesting(
from: T::CrossAccountId,
under: &T::CrossAccountId,
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -815,8 +815,9 @@
#[transactional]
pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
+ let budget = budget::Value::new(NESTING_BUDGET);
- dispatch_call::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))
+ dispatch_call::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount, &budget))
}
/// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.
runtime/common/src/runtime_apis.rsdiffbeforeafterboth1#[macro_export]2macro_rules! impl_common_runtime_apis {3 (4 $(5 #![custom_apis]67 $($custom_apis:tt)+8 )?9 ) => {10 impl_runtime_apis! {11 $($($custom_apis)+)?1213 impl up_rpc::UniqueApi<Block, CrossAccountId, AccountId> for Runtime {14 fn account_tokens(collection: CollectionId, account: CrossAccountId) -> Result<Vec<TokenId>, DispatchError> {15 dispatch_unique_runtime!(collection.account_tokens(account))16 }17 fn collection_tokens(collection: CollectionId) -> Result<Vec<TokenId>, DispatchError> {18 dispatch_unique_runtime!(collection.collection_tokens())19 }20 fn token_exists(collection: CollectionId, token: TokenId) -> Result<bool, DispatchError> {21 dispatch_unique_runtime!(collection.token_exists(token))22 }2324 fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {25 dispatch_unique_runtime!(collection.token_owner(token))26 }27 fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>, DispatchError> {28 let budget = up_data_structs::budget::Value::new(10);2930 Ok(Some(<pallet_structure::Pallet<Runtime>>::find_topmost_owner(collection, token, &budget)?))31 }32 fn token_children(collection: CollectionId, token: TokenId) -> Result<Vec<TokenChild>, DispatchError> {33 Ok(<pallet_nonfungible::Pallet<Runtime>>::token_children_ids(collection, token))34 }35 fn collection_properties(36 collection: CollectionId,37 keys: Option<Vec<Vec<u8>>>38 ) -> Result<Vec<Property>, DispatchError> {39 let keys = keys.map(40 |keys| Common::bytes_keys_to_property_keys(keys)41 ).transpose()?;4243 Common::filter_collection_properties(collection, keys)44 }4546 fn token_properties(47 collection: CollectionId,48 token_id: TokenId,49 keys: Option<Vec<Vec<u8>>>50 ) -> Result<Vec<Property>, DispatchError> {51 let keys = keys.map(52 |keys| Common::bytes_keys_to_property_keys(keys)53 ).transpose()?;5455 dispatch_unique_runtime!(collection.token_properties(token_id, keys))56 }5758 fn property_permissions(59 collection: CollectionId,60 keys: Option<Vec<Vec<u8>>>61 ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {62 let keys = keys.map(63 |keys| Common::bytes_keys_to_property_keys(keys)64 ).transpose()?;6566 Common::filter_property_permissions(collection, keys)67 }6869 fn token_data(70 collection: CollectionId,71 token_id: TokenId,72 keys: Option<Vec<Vec<u8>>>73 ) -> Result<TokenData<CrossAccountId>, DispatchError> {74 let token_data = TokenData {75 properties: Self::token_properties(collection, token_id, keys)?,76 owner: Self::token_owner(collection, token_id)?77 };7879 Ok(token_data)80 }8182 fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {83 dispatch_unique_runtime!(collection.total_supply())84 }85 fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {86 dispatch_unique_runtime!(collection.account_balance(account))87 }88 fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {89 dispatch_unique_runtime!(collection.balance(account, token))90 }91 fn allowance(92 collection: CollectionId,93 sender: CrossAccountId,94 spender: CrossAccountId,95 token: TokenId,96 ) -> Result<u128, DispatchError> {97 dispatch_unique_runtime!(collection.allowance(sender, spender, token))98 }99100 fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {101 Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))102 }103 fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {104 Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))105 }106 fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {107 Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))108 }109 fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {110 dispatch_unique_runtime!(collection.last_token_id())111 }112 fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>, DispatchError> {113 Ok(<pallet_common::Pallet<Runtime>>::rpc_collection(collection))114 }115 fn collection_stats() -> Result<CollectionStats, DispatchError> {116 Ok(<pallet_common::Pallet<Runtime>>::collection_stats())117 }118 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {119 Ok(<$crate::sponsoring::UniqueSponsorshipPredict<Runtime> as120 $crate::sponsoring::SponsorshipPredict<Runtime>>::predict(121 collection,122 account,123 token))124 }125126 fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {127 Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))128 }129 }130131 impl rmrk_rpc::RmrkApi<132 Block,133 AccountId,134 RmrkCollectionInfo<AccountId>,135 RmrkInstanceInfo<AccountId>,136 RmrkResourceInfo,137 RmrkPropertyInfo,138 RmrkBaseInfo<AccountId>,139 RmrkPartType,140 RmrkTheme141 > for Runtime {142 fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {143 Ok(RmrkCore::last_collection_idx())144 }145146 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {147 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};148 use pallet_common::CommonCollectionOperations;149150 let collection_id = match RmrkCore::unique_collection_id(collection_id) {151 Ok(id) => id,152 Err(_) => return Ok(None)153 };154155 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {156 Ok(c) => c,157 Err(_) => return Ok(None),158 };159160 let nfts_count = collection.total_supply();161162 Ok(Some(RmrkCollectionInfo {163 issuer: collection.owner.clone(),164 metadata: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::Metadata)?,165 max: collection.limits.token_limit,166 symbol: RmrkCore::rebind(&collection.token_prefix)?,167 nfts_count168 }))169 }170171 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {172 use up_data_structs::mapping::TokenAddressMapping;173 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};174 use pallet_common::CommonCollectionOperations;175176 let collection_id = match RmrkCore::unique_collection_id(collection_id) {177 Ok(id) => id,178 Err(_) => return Ok(None)179 };180 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {181 Ok(c) => c,182 Err(_) => return Ok(None),183 };184185 let nft_id = TokenId(nft_by_id);186 if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(None); }187188 let owner = match collection.token_owner(nft_id) {189 Some(owner) => match <Runtime as pallet_common::Config>::CrossTokenAddressMapping::address_to_token(&owner) {190 Some((col, tok)) => {191 let rmrk_collection = RmrkCore::rmrk_collection_id(col)?;192193 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(rmrk_collection, tok.0)194 }195 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone())196 },197 None => return Ok(None)198 };199200 let allowance = pallet_nonfungible::Allowance::<Runtime>::get((collection_id, nft_id));201202 Ok(Some(RmrkInstanceInfo {203 owner: owner,204 royalty: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?,205 metadata: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Metadata)?,206 equipped: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Equipped)?,207 pending: allowance.is_some(),208 }))209 }210211 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {212 use pallet_proxy_rmrk_core::misc::CollectionType;213 use pallet_common::CommonCollectionOperations;214215 let cross_account_id = CrossAccountId::from_sub(account_id);216 let collection_id = match RmrkCore::unique_collection_id(collection_id) {217 Ok(id) => id,218 Err(_) => return Ok(Vec::new())219 };220 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }221222 Ok(223 collection.account_tokens(cross_account_id)224 .into_iter()225 .map(|token| token.0)226 .collect()227 )228 }229230 fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {231 let collection_id = match RmrkCore::unique_collection_id(collection_id) {232 Ok(id) => id,233 Err(_) => return Ok(Vec::new())234 };235 let nft_id = TokenId(nft_id);236 if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(Vec::new()); }237238 Ok(239 pallet_nonfungible::TokenChildren::<Runtime>::iter_prefix((collection_id, nft_id))240 .filter_map(|((child_collection, child_token), _)| {241 let rmrk_child_collection = RmrkCore::rmrk_collection_id(242 child_collection243 ).ok()?;244245 Some(RmrkNftChild {246 collection_id: rmrk_child_collection,247 nft_id: child_token.0,248 })249 }).collect()250 )251 }252253 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {254 use pallet_proxy_rmrk_core::misc::CollectionType;255256 let collection_id = match RmrkCore::unique_collection_id(collection_id) {257 Ok(id) => id,258 Err(_) => return Ok(Vec::new())259 };260 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() {261 return Ok(Vec::new());262 }263264 let properties = RmrkCore::filter_user_properties(265 collection_id,266 /* token_id = */ None,267 filter_keys,268 |key, value| RmrkPropertyInfo {269 key,270 value271 }272 )?;273274 Ok(properties)275 }276277 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {278 use pallet_proxy_rmrk_core::misc::NftType;279280 let collection_id = match RmrkCore::unique_collection_id(collection_id) {281 Ok(id) => id,282 Err(_) => return Ok(Vec::new())283 };284 let token_id = TokenId(nft_id);285286 if RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {287 return Ok(Vec::new());288 }289290 let properties = RmrkCore::filter_user_properties(291 collection_id,292 Some(token_id),293 filter_keys,294 |key, value| RmrkPropertyInfo {295 key,296 value297 }298 )?;299300 Ok(properties)301 }302303 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {304 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, ResourceType}};305 use pallet_common::CommonCollectionOperations;306307 let collection_id = match RmrkCore::unique_collection_id(collection_id) {308 Ok(id) => id,309 Err(_) => return Ok(Vec::new())310 };311 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }312313 let nft_id = TokenId(nft_id);314 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }315316 let res_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;317 let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;318319 let resources = resource_collection320 .collection_tokens()321 .iter()322 .filter_map(|(res_id)| Some(RmrkResourceInfo {323 id: res_id.0,324 pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).unwrap(),325 pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).unwrap(),326 resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).unwrap() {327 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {328 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),329 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),330 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),331 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),332 }),333 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {334 parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).unwrap(),335 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),336 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),337 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),338 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),339 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),340 }),341 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {342 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),343 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),344 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),345 slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).unwrap(),346 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),347 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),348 }),349 },350 }))351 .collect();352353 Ok(resources)354 }355356 fn nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceId>, DispatchError> {357 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};358359 let collection_id = match RmrkCore::unique_collection_id(collection_id) {360 Ok(id) => id,361 Err(_) => return Ok(Vec::new())362 };363 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }364365 let nft_id = TokenId(nft_id);366 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }367368 /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)369 .unwrap();370 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }371372 let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))373 .filter_map(|(resource_id, properties)| Some((374 resource_id, // ResourceId property375 RmrkCore::get_nft_property_decoded(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap(),376 )))377 .collect()378 .sort_by_key(|(_, index)| *index)379 .into_iter().map(|(resource_id, _)| resource_id)*/380 let priorities = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourcePriorities)?;381382 Ok(priorities)383 }384385 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {386 use pallet_proxy_rmrk_core::{387 RmrkProperty, misc::{CollectionType},388 };389390 let collection_id = match RmrkCore::unique_collection_id(base_id) {391 Ok(id) => id,392 Err(_) => return Ok(None)393 };394 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Base) {395 Ok(c) => c,396 Err(_) => return Ok(None),397 };398399 Ok(Some(RmrkBaseInfo {400 issuer: collection.owner.clone(),401 base_type: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::BaseType)?,402 symbol: RmrkCore::rebind(&collection.token_prefix)?,403 }))404 }405406 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {407 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};408 use pallet_common::CommonCollectionOperations;409410 let collection_id = match RmrkCore::unique_collection_id(base_id) {411 Ok(id) => id,412 Err(_) => return Ok(Vec::new())413 };414 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() { return Ok(Vec::new()); }415416 let parts = collection.collection_tokens()417 .into_iter()418 .filter_map(|token_id| {419 let nft_type = RmrkCore::get_nft_type(collection_id, token_id).ok()?;420421 match nft_type {422 NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {423 id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,424 src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,425 z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,426 })),427 NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {428 id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,429 src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,430 z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,431 equippable: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::EquippableList).ok()?,432 })),433 _ => None434 }435 })436 .collect();437438 Ok(parts)439 }440441 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {442 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};443 use pallet_common::CommonCollectionOperations;444445 let collection_id = match RmrkCore::unique_collection_id(base_id) {446 Ok(id) => id,447 Err(_) => return Ok(Vec::new())448 };449 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {450 return Ok(Vec::new());451 }452453454 let theme_names = collection.collection_tokens()455 .iter()456 .filter_map(|token_id| {457 let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();458459 match nft_type {460 Theme => Some(461 RmrkCore::get_nft_property_decoded(collection_id, *token_id, RmrkProperty::ThemeName).unwrap()462 ),463 _ => None464 }465 })466 .collect();467468 Ok(theme_names)469 }470471 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {472 use pallet_proxy_rmrk_core::{473 RmrkProperty,474 misc::{CollectionType, NftType}475 };476 use pallet_common::CommonCollectionOperations;477478 let collection_id = match RmrkCore::unique_collection_id(base_id) {479 Ok(id) => id,480 Err(_) => return Ok(None)481 };482 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {483 return Ok(None);484 }485486 let theme_info = collection.collection_tokens()487 .into_iter()488 .find_map(|token_id| {489 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;490491 let name: RmrkString = RmrkCore::get_nft_property_decoded(492 collection_id, token_id, RmrkProperty::ThemeName493 ).ok()?;494495 if name == theme_name {496 Some((name, token_id))497 } else {498 None499 }500 });501502 let (name, theme_id) = match theme_info {503 Some((name, theme_id)) => (name, theme_id),504 None => return Ok(None)505 };506507 let properties = RmrkCore::filter_user_properties(508 collection_id,509 Some(theme_id),510 filter_keys,511 |key, value| RmrkThemeProperty {512 key,513 value514 }515 )?;516517 let inherit = RmrkCore::get_nft_property_decoded(518 collection_id,519 theme_id,520 RmrkProperty::ThemeInherit521 )?;522523 let theme = RmrkTheme {524 name,525 properties,526 inherit,527 };528529 Ok(Some(theme))530 }531 }532533 impl sp_api::Core<Block> for Runtime {534 fn version() -> RuntimeVersion {535 VERSION536 }537538 fn execute_block(block: Block) {539 Executive::execute_block(block)540 }541542 fn initialize_block(header: &<Block as BlockT>::Header) {543 Executive::initialize_block(header)544 }545 }546547 impl sp_api::Metadata<Block> for Runtime {548 fn metadata() -> OpaqueMetadata {549 OpaqueMetadata::new(Runtime::metadata().into())550 }551 }552553 impl sp_block_builder::BlockBuilder<Block> for Runtime {554 fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {555 Executive::apply_extrinsic(extrinsic)556 }557558 fn finalize_block() -> <Block as BlockT>::Header {559 Executive::finalize_block()560 }561562 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {563 data.create_extrinsics()564 }565566 fn check_inherents(567 block: Block,568 data: sp_inherents::InherentData,569 ) -> sp_inherents::CheckInherentsResult {570 data.check_extrinsics(&block)571 }572573 // fn random_seed() -> <Block as BlockT>::Hash {574 // RandomnessCollectiveFlip::random_seed().0575 // }576 }577578 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {579 fn validate_transaction(580 source: TransactionSource,581 tx: <Block as BlockT>::Extrinsic,582 hash: <Block as BlockT>::Hash,583 ) -> TransactionValidity {584 Executive::validate_transaction(source, tx, hash)585 }586 }587588 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {589 fn offchain_worker(header: &<Block as BlockT>::Header) {590 Executive::offchain_worker(header)591 }592 }593594 impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {595 fn chain_id() -> u64 {596 <Runtime as pallet_evm::Config>::ChainId::get()597 }598599 fn account_basic(address: H160) -> EVMAccount {600 let (account, _) = EVM::account_basic(&address);601 account602 }603604 fn gas_price() -> U256 {605 let (price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();606 price607 }608609 fn account_code_at(address: H160) -> Vec<u8> {610 EVM::account_codes(address)611 }612613 fn author() -> H160 {614 <pallet_evm::Pallet<Runtime>>::find_author()615 }616617 fn storage_at(address: H160, index: U256) -> H256 {618 let mut tmp = [0u8; 32];619 index.to_big_endian(&mut tmp);620 EVM::account_storages(address, H256::from_slice(&tmp[..]))621 }622623 #[allow(clippy::redundant_closure)]624 fn call(625 from: H160,626 to: H160,627 data: Vec<u8>,628 value: U256,629 gas_limit: U256,630 max_fee_per_gas: Option<U256>,631 max_priority_fee_per_gas: Option<U256>,632 nonce: Option<U256>,633 estimate: bool,634 access_list: Option<Vec<(H160, Vec<H256>)>>,635 ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {636 let config = if estimate {637 let mut config = <Runtime as pallet_evm::Config>::config().clone();638 config.estimate = true;639 Some(config)640 } else {641 None642 };643644 let is_transactional = false;645 <Runtime as pallet_evm::Config>::Runner::call(646 CrossAccountId::from_eth(from),647 to,648 data,649 value,650 gas_limit.low_u64(),651 max_fee_per_gas,652 max_priority_fee_per_gas,653 nonce,654 access_list.unwrap_or_default(),655 is_transactional,656 config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),657 ).map_err(|err| err.error.into())658 }659660 #[allow(clippy::redundant_closure)]661 fn create(662 from: H160,663 data: Vec<u8>,664 value: U256,665 gas_limit: U256,666 max_fee_per_gas: Option<U256>,667 max_priority_fee_per_gas: Option<U256>,668 nonce: Option<U256>,669 estimate: bool,670 access_list: Option<Vec<(H160, Vec<H256>)>>,671 ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {672 let config = if estimate {673 let mut config = <Runtime as pallet_evm::Config>::config().clone();674 config.estimate = true;675 Some(config)676 } else {677 None678 };679680 let is_transactional = false;681 <Runtime as pallet_evm::Config>::Runner::create(682 CrossAccountId::from_eth(from),683 data,684 value,685 gas_limit.low_u64(),686 max_fee_per_gas,687 max_priority_fee_per_gas,688 nonce,689 access_list.unwrap_or_default(),690 is_transactional,691 config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),692 ).map_err(|err| err.error.into())693 }694695 fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {696 Ethereum::current_transaction_statuses()697 }698699 fn current_block() -> Option<pallet_ethereum::Block> {700 Ethereum::current_block()701 }702703 fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {704 Ethereum::current_receipts()705 }706707 fn current_all() -> (708 Option<pallet_ethereum::Block>,709 Option<Vec<pallet_ethereum::Receipt>>,710 Option<Vec<TransactionStatus>>711 ) {712 (713 Ethereum::current_block(),714 Ethereum::current_receipts(),715 Ethereum::current_transaction_statuses()716 )717 }718719 fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {720 xts.into_iter().filter_map(|xt| match xt.0.function {721 Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),722 _ => None723 }).collect()724 }725726 fn elasticity() -> Option<Permill> {727 None728 }729 }730731 impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {732 fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {733 UncheckedExtrinsic::new_unsigned(734 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),735 )736 }737 }738739 impl sp_session::SessionKeys<Block> for Runtime {740 fn decode_session_keys(741 encoded: Vec<u8>,742 ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {743 SessionKeys::decode_into_raw_public_keys(&encoded)744 }745746 fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {747 SessionKeys::generate(seed)748 }749 }750751 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {752 fn slot_duration() -> sp_consensus_aura::SlotDuration {753 sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())754 }755756 fn authorities() -> Vec<AuraId> {757 Aura::authorities().to_vec()758 }759 }760761 impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {762 fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {763 ParachainSystem::collect_collation_info(header)764 }765 }766767 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {768 fn account_nonce(account: AccountId) -> Index {769 System::account_nonce(account)770 }771 }772773 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {774 fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {775 TransactionPayment::query_info(uxt, len)776 }777 fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {778 TransactionPayment::query_fee_details(uxt, len)779 }780 }781782 /*783 impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>784 for Runtime785 {786 fn call(787 origin: AccountId,788 dest: AccountId,789 value: Balance,790 gas_limit: u64,791 input_data: Vec<u8>,792 ) -> pallet_contracts_primitives::ContractExecResult {793 Contracts::bare_call(origin, dest, value, gas_limit, input_data, false)794 }795796 fn instantiate(797 origin: AccountId,798 endowment: Balance,799 gas_limit: u64,800 code: pallet_contracts_primitives::Code<Hash>,801 data: Vec<u8>,802 salt: Vec<u8>,803 ) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>804 {805 Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false)806 }807808 fn get_storage(809 address: AccountId,810 key: [u8; 32],811 ) -> pallet_contracts_primitives::GetStorageResult {812 Contracts::get_storage(address, key)813 }814815 fn rent_projection(816 address: AccountId,817 ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {818 Contracts::rent_projection(address)819 }820 }821 */822823 #[cfg(feature = "runtime-benchmarks")]824 impl frame_benchmarking::Benchmark<Block> for Runtime {825 fn benchmark_metadata(extra: bool) -> (826 Vec<frame_benchmarking::BenchmarkList>,827 Vec<frame_support::traits::StorageInfo>,828 ) {829 use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};830 use frame_support::traits::StorageInfoTrait;831832 let mut list = Vec::<BenchmarkList>::new();833834 list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);835 list_benchmark!(list, extra, pallet_common, Common);836 list_benchmark!(list, extra, pallet_unique, Unique);837 list_benchmark!(list, extra, pallet_structure, Structure);838 list_benchmark!(list, extra, pallet_inflation, Inflation);839 list_benchmark!(list, extra, pallet_fungible, Fungible);840 list_benchmark!(list, extra, pallet_refungible, Refungible);841 list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);842 // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate);843844 let storage_info = AllPalletsReversedWithSystemFirst::storage_info();845846 return (list, storage_info)847 }848849 fn dispatch_benchmark(850 config: frame_benchmarking::BenchmarkConfig851 ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {852 use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};853854 let allowlist: Vec<TrackedStorageKey> = vec![855 // Total Issuance856 hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),857858 // Block Number859 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),860 // Execution Phase861 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),862 // Event Count863 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),864 // System Events865 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),866867 // Evm CurrentLogs868 hex_literal::hex!("1da53b775b270400e7e61ed5cbc5a146547f210cec367e9af919603343b9cb56").to_vec().into(),869870 // Transactional depth871 hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),872 ];873874 let mut batches = Vec::<BenchmarkBatch>::new();875 let params = (&config, &allowlist);876877 add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);878 add_benchmark!(params, batches, pallet_common, Common);879 add_benchmark!(params, batches, pallet_unique, Unique);880 add_benchmark!(params, batches, pallet_structure, Structure);881 add_benchmark!(params, batches, pallet_inflation, Inflation);882 add_benchmark!(params, batches, pallet_fungible, Fungible);883 add_benchmark!(params, batches, pallet_refungible, Refungible);884 add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);885 // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);886887 if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }888 Ok(batches)889 }890 }891892 #[cfg(feature = "try-runtime")]893 impl frame_try_runtime::TryRuntime<Block> for Runtime {894 fn on_runtime_upgrade() -> (Weight, Weight) {895 log::info!("try-runtime::on_runtime_upgrade unique-chain.");896 let weight = Executive::try_runtime_upgrade().unwrap();897 (weight, RuntimeBlockWeights::get().max_block)898 }899900 fn execute_block_no_check(block: Block) -> Weight {901 Executive::execute_block_no_check(block)902 }903 }904 }905 }906}