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 = RmrkCore::unique_collection_id(collection_id)?;151 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {152 Ok(c) => c,153 Err(_) => return Ok(None),154 };155156 let nfts_count = collection.total_supply();157158 Ok(Some(RmrkCollectionInfo {159 issuer: collection.owner.clone(),160 metadata: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::Metadata)?,161 max: collection.limits.token_limit,162 symbol: RmrkCore::rebind(&collection.token_prefix)?,163 nfts_count164 }))165 }166167 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {168 use up_data_structs::mapping::TokenAddressMapping;169 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};170 use pallet_common::CommonCollectionOperations;171172 let collection_id = RmrkCore::unique_collection_id(collection_id)?;173 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {174 Ok(c) => c,175 Err(_) => return Ok(None),176 };177178 let nft_id = TokenId(nft_by_id);179 if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(None); }180181 let owner = match collection.token_owner(nft_id) {182 Some(owner) => match <Runtime as pallet_common::Config>::CrossTokenAddressMapping::address_to_token(&owner) {183 Some((col, tok)) => RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(col.0, tok.0),184 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone())185 },186 None => return Ok(None)187 };188189 let allowance = pallet_nonfungible::Allowance::<Runtime>::get((collection_id, nft_id));190191 Ok(Some(RmrkInstanceInfo {192 owner: owner,193 royalty: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?,194 metadata: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Metadata)?,195 equipped: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Equipped)?,196 pending: allowance.is_some(),197 }))198 }199200 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {201 use pallet_proxy_rmrk_core::misc::CollectionType;202 use pallet_common::CommonCollectionOperations;203204 let cross_account_id = CrossAccountId::from_sub(account_id);205 let collection_id = RmrkCore::unique_collection_id(collection_id)?;206 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {207 Ok(c) => c,208 Err(_) => return Ok(Vec::new()),209 };210211 Ok(212 collection.account_tokens(cross_account_id)213 .into_iter()214 .map(|token| token.0)215 .collect()216 )217 }218219 fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {220 let collection_id = RmrkCore::unique_collection_id(collection_id)?;221 let nft_id = TokenId(nft_id);222 if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(Vec::new()); }223224 Ok(225 pallet_nonfungible::TokenChildren::<Runtime>::iter_prefix((collection_id, nft_id))226 .filter_map(|(child_id, is_child)|227 match is_child {228 true => Some(RmrkNftChild {229 collection_id: child_id.0.0,230 nft_id: child_id.1.0,231 }),232 false => None,233 }234 ).collect()235 )236 }237238 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {239 use pallet_proxy_rmrk_core::misc::CollectionType;240241 let collection_id = RmrkCore::unique_collection_id(collection_id)?;242 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() {243 return Ok(Vec::new());244 }245246 let properties = RmrkCore::filter_user_properties(247 collection_id,248 /* token_id = */ None,249 filter_keys,250 |key, value| RmrkPropertyInfo {251 key,252 value253 }254 )?;255256 Ok(properties)257 }258259 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {260 use pallet_proxy_rmrk_core::misc::NftType;261262 let collection_id = RmrkCore::unique_collection_id(collection_id)?;263 let token_id = TokenId(nft_id);264265 if RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {266 return Ok(Vec::new());267 }268269 let properties = RmrkCore::filter_user_properties(270 collection_id,271 Some(token_id),272 filter_keys,273 |key, value| RmrkPropertyInfo {274 key,275 value276 }277 )?;278279 Ok(properties)280 }281282 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {283 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, ResourceType}};284 use pallet_common::CommonCollectionOperations;285286 let collection_id = RmrkCore::unique_collection_id(collection_id)?;287 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }288289 let nft_id = TokenId(nft_id);290 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }291292 let res_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;293 let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;294295 let resources = resource_collection296 .collection_tokens()297 .iter()298 .filter_map(|(res_id)| Some(RmrkResourceInfo {299 id: res_id.0,300 pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).unwrap(),301 pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).unwrap(),302 resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).unwrap() {303 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {304 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),305 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),306 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),307 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),308 }),309 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {310 parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).unwrap(),311 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),312 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),313 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),314 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),315 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),316 }),317 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {318 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),319 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),320 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),321 slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).unwrap(),322 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),323 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),324 }),325 },326 }))327 .collect();328329 Ok(resources)330 }331332 fn nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceId>, DispatchError> {333 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};334335 let collection_id = RmrkCore::unique_collection_id(collection_id)?;336 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }337338 let nft_id = TokenId(nft_id);339 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }340341 /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)342 .unwrap();343 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }344345 let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))346 .filter_map(|(resource_id, properties)| Some((347 resource_id, // ResourceId property348 RmrkCore::get_nft_property_decoded(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap(),349 )))350 .collect()351 .sort_by_key(|(_, index)| *index)352 .into_iter().map(|(resource_id, _)| resource_id)*/353 let priorities = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourcePriorities)?;354355 Ok(priorities)356 }357358 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {359 use pallet_proxy_rmrk_core::{360 RmrkProperty, misc::{CollectionType},361 };362363 let collection_id = RmrkCore::unique_collection_id(base_id)?;364 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Base) {365 Ok(c) => c,366 Err(_) => return Ok(None),367 };368369 Ok(Some(RmrkBaseInfo {370 issuer: collection.owner.clone(),371 base_type: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::BaseType)?,372 symbol: RmrkCore::rebind(&collection.token_prefix)?,373 }))374 }375376 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {377 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};378 use pallet_common::CommonCollectionOperations;379380 let collection_id = RmrkCore::unique_collection_id(base_id)?;381 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Base) {382 Ok(c) => c,383 Err(_) => return Ok(Vec::new()),384 };385386387 let parts = collection.collection_tokens()388 .into_iter()389 .filter_map(|token_id| {390 let nft_type = RmrkCore::get_nft_type(collection_id, token_id).ok()?;391392 match nft_type {393 NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {394 id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,395 src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,396 z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,397 })),398 NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {399 id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,400 src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,401 z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,402 equippable: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::EquippableList).ok()?,403 })),404 _ => None405 }406 })407 .collect();408409 Ok(parts)410 }411412 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {413 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};414 use pallet_common::CommonCollectionOperations;415416 let collection_id = RmrkCore::unique_collection_id(base_id)?;417 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Base) {418 Ok(c) => c,419 Err(_) => return Ok(Vec::new()),420 };421422423 let theme_names = collection.collection_tokens()424 .iter()425 .filter_map(|token_id| {426 let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();427428 match nft_type {429 Theme => Some(430 RmrkCore::get_nft_property_decoded(collection_id, *token_id, RmrkProperty::ThemeName).unwrap()431 ),432 _ => None433 }434 })435 .collect();436437 Ok(theme_names)438 }439440 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {441 use pallet_proxy_rmrk_core::{442 RmrkProperty,443 misc::{CollectionType, NftType}444 };445 use pallet_common::CommonCollectionOperations;446447 let collection_id = RmrkCore::unique_collection_id(base_id)?;448 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Base) {449 Ok(c) => c,450 Err(_) => return Ok(None),451 };452453 let theme_info = collection.collection_tokens()454 .into_iter()455 .find_map(|token_id| {456 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;457458 let name: RmrkString = RmrkCore::get_nft_property_decoded(459 collection_id, token_id, RmrkProperty::ThemeName460 ).ok()?;461462 if name == theme_name {463 Some((name, token_id))464 } else {465 None466 }467 });468469 let (name, theme_id) = match theme_info {470 Some((name, theme_id)) => (name, theme_id),471 None => return Ok(None)472 };473474 let properties = RmrkCore::filter_user_properties(475 collection_id,476 Some(theme_id),477 filter_keys,478 |key, value| RmrkThemeProperty {479 key,480 value481 }482 )?;483484 let inherit = RmrkCore::get_nft_property_decoded(485 collection_id,486 theme_id,487 RmrkProperty::ThemeInherit488 )?;489490 let theme = RmrkTheme {491 name,492 properties,493 inherit,494 };495496 Ok(Some(theme))497 }498 }499500 impl sp_api::Core<Block> for Runtime {501 fn version() -> RuntimeVersion {502 VERSION503 }504505 fn execute_block(block: Block) {506 Executive::execute_block(block)507 }508509 fn initialize_block(header: &<Block as BlockT>::Header) {510 Executive::initialize_block(header)511 }512 }513514 impl sp_api::Metadata<Block> for Runtime {515 fn metadata() -> OpaqueMetadata {516 OpaqueMetadata::new(Runtime::metadata().into())517 }518 }519520 impl sp_block_builder::BlockBuilder<Block> for Runtime {521 fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {522 Executive::apply_extrinsic(extrinsic)523 }524525 fn finalize_block() -> <Block as BlockT>::Header {526 Executive::finalize_block()527 }528529 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {530 data.create_extrinsics()531 }532533 fn check_inherents(534 block: Block,535 data: sp_inherents::InherentData,536 ) -> sp_inherents::CheckInherentsResult {537 data.check_extrinsics(&block)538 }539540 // fn random_seed() -> <Block as BlockT>::Hash {541 // RandomnessCollectiveFlip::random_seed().0542 // }543 }544545 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {546 fn validate_transaction(547 source: TransactionSource,548 tx: <Block as BlockT>::Extrinsic,549 hash: <Block as BlockT>::Hash,550 ) -> TransactionValidity {551 Executive::validate_transaction(source, tx, hash)552 }553 }554555 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {556 fn offchain_worker(header: &<Block as BlockT>::Header) {557 Executive::offchain_worker(header)558 }559 }560561 impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {562 fn chain_id() -> u64 {563 <Runtime as pallet_evm::Config>::ChainId::get()564 }565566 fn account_basic(address: H160) -> EVMAccount {567 let (account, _) = EVM::account_basic(&address);568 account569 }570571 fn gas_price() -> U256 {572 let (price, _) = <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price();573 price574 }575576 fn account_code_at(address: H160) -> Vec<u8> {577 EVM::account_codes(address)578 }579580 fn author() -> H160 {581 <pallet_evm::Pallet<Runtime>>::find_author()582 }583584 fn storage_at(address: H160, index: U256) -> H256 {585 let mut tmp = [0u8; 32];586 index.to_big_endian(&mut tmp);587 EVM::account_storages(address, H256::from_slice(&tmp[..]))588 }589590 #[allow(clippy::redundant_closure)]591 fn call(592 from: H160,593 to: H160,594 data: Vec<u8>,595 value: U256,596 gas_limit: U256,597 max_fee_per_gas: Option<U256>,598 max_priority_fee_per_gas: Option<U256>,599 nonce: Option<U256>,600 estimate: bool,601 access_list: Option<Vec<(H160, Vec<H256>)>>,602 ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {603 let config = if estimate {604 let mut config = <Runtime as pallet_evm::Config>::config().clone();605 config.estimate = true;606 Some(config)607 } else {608 None609 };610611 let is_transactional = false;612 <Runtime as pallet_evm::Config>::Runner::call(613 CrossAccountId::from_eth(from),614 to,615 data,616 value,617 gas_limit.low_u64(),618 max_fee_per_gas,619 max_priority_fee_per_gas,620 nonce,621 access_list.unwrap_or_default(),622 is_transactional,623 config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),624 ).map_err(|err| err.error.into())625 }626627 #[allow(clippy::redundant_closure)]628 fn create(629 from: H160,630 data: Vec<u8>,631 value: U256,632 gas_limit: U256,633 max_fee_per_gas: Option<U256>,634 max_priority_fee_per_gas: Option<U256>,635 nonce: Option<U256>,636 estimate: bool,637 access_list: Option<Vec<(H160, Vec<H256>)>>,638 ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {639 let config = if estimate {640 let mut config = <Runtime as pallet_evm::Config>::config().clone();641 config.estimate = true;642 Some(config)643 } else {644 None645 };646647 let is_transactional = false;648 <Runtime as pallet_evm::Config>::Runner::create(649 CrossAccountId::from_eth(from),650 data,651 value,652 gas_limit.low_u64(),653 max_fee_per_gas,654 max_priority_fee_per_gas,655 nonce,656 access_list.unwrap_or_default(),657 is_transactional,658 config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),659 ).map_err(|err| err.error.into())660 }661662 fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {663 Ethereum::current_transaction_statuses()664 }665666 fn current_block() -> Option<pallet_ethereum::Block> {667 Ethereum::current_block()668 }669670 fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {671 Ethereum::current_receipts()672 }673674 fn current_all() -> (675 Option<pallet_ethereum::Block>,676 Option<Vec<pallet_ethereum::Receipt>>,677 Option<Vec<TransactionStatus>>678 ) {679 (680 Ethereum::current_block(),681 Ethereum::current_receipts(),682 Ethereum::current_transaction_statuses()683 )684 }685686 fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {687 xts.into_iter().filter_map(|xt| match xt.0.function {688 Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),689 _ => None690 }).collect()691 }692693 fn elasticity() -> Option<Permill> {694 None695 }696 }697698 impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {699 fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {700 UncheckedExtrinsic::new_unsigned(701 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),702 )703 }704 }705706 impl sp_session::SessionKeys<Block> for Runtime {707 fn decode_session_keys(708 encoded: Vec<u8>,709 ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {710 SessionKeys::decode_into_raw_public_keys(&encoded)711 }712713 fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {714 SessionKeys::generate(seed)715 }716 }717718 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {719 fn slot_duration() -> sp_consensus_aura::SlotDuration {720 sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())721 }722723 fn authorities() -> Vec<AuraId> {724 Aura::authorities().to_vec()725 }726 }727728 impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {729 fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {730 ParachainSystem::collect_collation_info(header)731 }732 }733734 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {735 fn account_nonce(account: AccountId) -> Index {736 System::account_nonce(account)737 }738 }739740 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {741 fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {742 TransactionPayment::query_info(uxt, len)743 }744 fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {745 TransactionPayment::query_fee_details(uxt, len)746 }747 }748749 /*750 impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>751 for Runtime752 {753 fn call(754 origin: AccountId,755 dest: AccountId,756 value: Balance,757 gas_limit: u64,758 input_data: Vec<u8>,759 ) -> pallet_contracts_primitives::ContractExecResult {760 Contracts::bare_call(origin, dest, value, gas_limit, input_data, false)761 }762763 fn instantiate(764 origin: AccountId,765 endowment: Balance,766 gas_limit: u64,767 code: pallet_contracts_primitives::Code<Hash>,768 data: Vec<u8>,769 salt: Vec<u8>,770 ) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, BlockNumber>771 {772 Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, false)773 }774775 fn get_storage(776 address: AccountId,777 key: [u8; 32],778 ) -> pallet_contracts_primitives::GetStorageResult {779 Contracts::get_storage(address, key)780 }781782 fn rent_projection(783 address: AccountId,784 ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {785 Contracts::rent_projection(address)786 }787 }788 */789790 #[cfg(feature = "runtime-benchmarks")]791 impl frame_benchmarking::Benchmark<Block> for Runtime {792 fn benchmark_metadata(extra: bool) -> (793 Vec<frame_benchmarking::BenchmarkList>,794 Vec<frame_support::traits::StorageInfo>,795 ) {796 use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};797 use frame_support::traits::StorageInfoTrait;798799 let mut list = Vec::<BenchmarkList>::new();800801 list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);802 list_benchmark!(list, extra, pallet_common, Common);803 list_benchmark!(list, extra, pallet_unique, Unique);804 list_benchmark!(list, extra, pallet_structure, Structure);805 list_benchmark!(list, extra, pallet_inflation, Inflation);806 list_benchmark!(list, extra, pallet_fungible, Fungible);807 list_benchmark!(list, extra, pallet_refungible, Refungible);808 list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);809 // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate);810811 let storage_info = AllPalletsReversedWithSystemFirst::storage_info();812813 return (list, storage_info)814 }815816 fn dispatch_benchmark(817 config: frame_benchmarking::BenchmarkConfig818 ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {819 use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};820821 let allowlist: Vec<TrackedStorageKey> = vec![822 // Total Issuance823 hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),824825 // Block Number826 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),827 // Execution Phase828 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),829 // Event Count830 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),831 // System Events832 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),833834 // Evm CurrentLogs835 hex_literal::hex!("1da53b775b270400e7e61ed5cbc5a146547f210cec367e9af919603343b9cb56").to_vec().into(),836837 // Transactional depth838 hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),839 ];840841 let mut batches = Vec::<BenchmarkBatch>::new();842 let params = (&config, &allowlist);843844 add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);845 add_benchmark!(params, batches, pallet_common, Common);846 add_benchmark!(params, batches, pallet_unique, Unique);847 add_benchmark!(params, batches, pallet_structure, Structure);848 add_benchmark!(params, batches, pallet_inflation, Inflation);849 add_benchmark!(params, batches, pallet_fungible, Fungible);850 add_benchmark!(params, batches, pallet_refungible, Refungible);851 add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);852 // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate);853854 if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }855 Ok(batches)856 }857 }858859 #[cfg(feature = "try-runtime")]860 impl frame_try_runtime::TryRuntime<Block> for Runtime {861 fn on_runtime_upgrade() -> (Weight, Weight) {862 log::info!("try-runtime::on_runtime_upgrade unique-chain.");863 let weight = Executive::try_runtime_upgrade().unwrap();864 (weight, RuntimeBlockWeights::get().max_block)865 }866867 fn execute_block_no_check(block: Block) -> Weight {868 Executive::execute_block_no_check(block)869 }870 }871 }872 }873}