1#[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(5);2930 Ok(Some(<pallet_structure::Pallet<Runtime>>::find_topmost_owner(collection, token, &budget)?))31 }32 fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {33 dispatch_unique_runtime!(collection.const_metadata(token))34 }35 fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {36 dispatch_unique_runtime!(collection.variable_metadata(token))37 }3839 fn collection_properties(40 collection: CollectionId,41 keys: Vec<Vec<u8>>42 ) -> Result<Vec<Property>, DispatchError> {43 let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;4445 pallet_common::Pallet::<Runtime>::filter_collection_properties(collection, keys)46 }4748 fn token_properties(49 collection: CollectionId,50 token_id: TokenId,51 keys: Vec<Vec<u8>>52 ) -> Result<Vec<Property>, DispatchError> {53 let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;54 dispatch_unique_runtime!(collection.token_properties(token_id, keys))55 }5657 fn property_permissions(58 collection: CollectionId,59 keys: Vec<Vec<u8>>60 ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {61 let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;6263 pallet_common::Pallet::<Runtime>::filter_property_permissions(collection, keys)64 }6566 fn token_data(67 collection: CollectionId,68 token_id: TokenId,69 keys: Vec<Vec<u8>>70 ) -> Result<TokenData<CrossAccountId>, DispatchError> {71 let token_data = TokenData {72 const_data: Self::const_metadata(collection, token_id)?,73 properties: Self::token_properties(collection, token_id, keys)?,74 owner: Self::token_owner(collection, token_id)?75 };7677 Ok(token_data)78 }7980 fn total_supply(collection: CollectionId) -> Result<u32, DispatchError> {81 dispatch_unique_runtime!(collection.total_supply())82 }83 fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32, DispatchError> {84 dispatch_unique_runtime!(collection.account_balance(account))85 }86 fn balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<u128, DispatchError> {87 dispatch_unique_runtime!(collection.balance(account, token))88 }89 fn allowance(90 collection: CollectionId,91 sender: CrossAccountId,92 spender: CrossAccountId,93 token: TokenId,94 ) -> Result<u128, DispatchError> {95 dispatch_unique_runtime!(collection.allowance(sender, spender, token))96 }9798 fn adminlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {99 Ok(<pallet_common::Pallet<Runtime>>::adminlist(collection))100 }101 fn allowlist(collection: CollectionId) -> Result<Vec<CrossAccountId>, DispatchError> {102 Ok(<pallet_common::Pallet<Runtime>>::allowlist(collection))103 }104 fn allowed(collection: CollectionId, user: CrossAccountId) -> Result<bool, DispatchError> {105 Ok(<pallet_common::Pallet<Runtime>>::allowed(collection, user))106 }107 fn last_token_id(collection: CollectionId) -> Result<TokenId, DispatchError> {108 dispatch_unique_runtime!(collection.last_token_id())109 }110 fn collection_by_id(collection: CollectionId) -> Result<Option<RpcCollection<AccountId>>, DispatchError> {111 Ok(<pallet_common::Pallet<Runtime>>::rpc_collection(collection))112 }113 fn collection_stats() -> Result<CollectionStats, DispatchError> {114 Ok(<pallet_common::Pallet<Runtime>>::collection_stats())115 }116 fn next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Result<Option<u64>, DispatchError> {117 Ok(<$crate::sponsoring::UniqueSponsorshipPredict<Runtime> as118 $crate::sponsoring::SponsorshipPredict<Runtime>>::predict(119 collection,120 account,121 token))122 }123124 fn effective_collection_limits(collection: CollectionId) -> Result<Option<CollectionLimits>, DispatchError> {125 Ok(<pallet_common::Pallet<Runtime>>::effective_collection_limits(collection))126 }127 }128129 impl rmrk_rpc::RmrkApi<130 Block,131 AccountId,132 RmrkCollectionInfo<AccountId>,133 RmrkInstanceInfo<AccountId>,134 RmrkResourceInfo,135 RmrkPropertyInfo,136 RmrkBaseInfo<AccountId>,137 RmrkPartType,138 RmrkTheme139 > for Runtime {140 fn last_collection_idx() -> Result<RmrkCollectionId, DispatchError> {141 Ok(<pallet_common::CreatedCollectionCount<Runtime>>::get().0)142 }143 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {144 145 use frame_support::BoundedVec;146147 let collection_id = CollectionId(collection_id);148 let collection = match <pallet_common::CollectionById<Runtime>>::get(collection_id) {149 Some(c) => c,150 None => return Ok(None)151 };152 let nfts_count: Result<u32, DispatchError> = dispatch_unique_runtime!(collection_id.total_supply());153 Ok(Some(RmrkCollectionInfo {154 issuer: collection.owner,155 metadata: BoundedVec::default(), 156 max: Some(collection.limits.token_limit()), 157 symbol: BoundedVec::try_from(collection.token_prefix.into_inner()).unwrap_or_default() 158159160,161 nfts_count: nfts_count? 162 }))163 }164 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {165 use frame_support::BoundedVec;166 use up_data_structs::mapping::TokenAddressMapping;167168 let collection_id = CollectionId(collection_id);169 let nft_id = TokenId(nft_by_id);170171 let owner = match (dispatch_unique_runtime!(collection_id.token_owner(nft_id)) as Result<Option<CrossAccountId>, DispatchError>)? {172 Some(owner) => match <Runtime as pallet_common::Config>::CrossTokenAddressMapping::address_to_token(&owner) {173 Some((col, tok)) => RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(col.0, tok.0),174 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone())175 },176 None => return Ok(None)177 };178179 Ok(Some(RmrkInstanceInfo {180 owner: owner,181 182 royalty: None,183 metadata: BoundedVec::default(), 184 equipped: false, 185 pending: false, 186 }))187 }188 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {189 let cross_account_id = CrossAccountId::from_sub(account_id);190 let collection_id = CollectionId(collection_id);191 Ok(192 (dispatch_unique_runtime!(collection_id.account_tokens(cross_account_id)) as Result<Vec<TokenId>, DispatchError>)?193 194 .into_iter()195 .map(|token| token.0)196 .collect::<Vec<_>>()197 )198 }199 fn nft_children(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkNftChild>, DispatchError> {200 use up_data_structs::mapping::TokenAddressMapping;201202 let collection_id = CollectionId(collection_id);203 let nft_id = TokenId(nft_id);204 let cross_account_id = CrossAccountId::from_eth(205 EvmTokenAddressMapping::token_to_address(collection_id, nft_id)206 );207208 Ok(209 pallet_nonfungible::Owned::<Runtime>::iter_prefix((collection_id, cross_account_id))210 .map(|(child_id, _)| RmrkNftChild {211 collection_id: collection_id.0, 212 nft_id: child_id.0,213 })214 .collect()215 )216 }217 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {218 use frame_support::BoundedVec;219220 let collection_id = CollectionId(collection_id);221 let properties = pallet_common::Pallet::<Runtime>::collection_properties(collection_id);222223 return Ok(match filter_keys {224 Some(keys) => {225 let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;226 let properties = keys227 .into_iter()228 .filter_map(|key| {229 properties.get(&key).map(|value| RmrkPropertyInfo {230 key: BoundedVec::try_from(key.into_inner()).unwrap_or_default(),231 value: BoundedVec::try_from(value.clone().into_inner()).unwrap_or_default(),232 })233 })234 .collect();235 236 properties237 }238 None => {239 properties240 .iter()241 .map(|(key, value)| RmrkPropertyInfo {242 key: BoundedVec::try_from(key.clone().into_inner()).unwrap_or_default(),243 value: BoundedVec::try_from(value.clone().into_inner()).unwrap_or_default(),244 })245 .collect()246 }247 });248 }249 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {250 use frame_support::BoundedVec;251252 let collection_id = CollectionId(collection_id);253 let token_id = TokenId(nft_id);254255 let properties = pallet_nonfungible::Pallet::<Runtime>::token_properties((collection_id, token_id)); 256 257 return Ok(match filter_keys {258 Some(keys) => {259 let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;260 let properties = keys261 .into_iter()262 .filter_map(|key| {263 properties.get(&key).map(|value| RmrkPropertyInfo {264 key: BoundedVec::try_from(key.into_inner()).unwrap_or_default(),265 value: BoundedVec::try_from(value.clone().into_inner()).unwrap_or_default(),266 })267 })268 .collect();269 270 properties271 }272 None => {273 properties274 .iter()275 .map(|(key, value)| RmrkPropertyInfo {276 key: BoundedVec::try_from(key.clone().into_inner()).unwrap_or_default(),277 value: BoundedVec::try_from(value.clone().into_inner()).unwrap_or_default(),278 })279 .collect()280 }281 });282 }283 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {284 todo!()285 }286 fn nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceId>, DispatchError> {287 todo!()288 }289 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {290 use frame_support::{BoundedVec, ensure};291 use scale_info::prelude::string::String;292293 let collection_id = CollectionId(base_id);294 let collection = match <pallet_common::CollectionById<Runtime>>::get(collection_id) {295 Some(c) => c,296 None => return Ok(None)297 };298299 300 let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(301 Vec::from([String::from("rmrk:base-type").into_bytes()])302 )?;303 let properties = pallet_common::Pallet::<Runtime>::filter_collection_properties(collection_id, keys)?;304 305306 Ok(Some( RmrkBaseInfo {307 issuer: collection.owner,308 base_type: BoundedVec::try_from(properties[0].value.clone().into_inner()).unwrap_or_default(), 309 symbol: BoundedVec::try_from(collection.token_prefix.into_inner()).unwrap_or_default(),310 }))311 }312 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {313 todo!()314 }315 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {316 todo!()317 }318 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {319 todo!()320 }321 }322323 impl sp_api::Core<Block> for Runtime {324 fn version() -> RuntimeVersion {325 VERSION326 }327328 fn execute_block(block: Block) {329 Executive::execute_block(block)330 }331332 fn initialize_block(header: &<Block as BlockT>::Header) {333 Executive::initialize_block(header)334 }335 }336337 impl sp_api::Metadata<Block> for Runtime {338 fn metadata() -> OpaqueMetadata {339 OpaqueMetadata::new(Runtime::metadata().into())340 }341 }342343 impl sp_block_builder::BlockBuilder<Block> for Runtime {344 fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {345 Executive::apply_extrinsic(extrinsic)346 }347348 fn finalize_block() -> <Block as BlockT>::Header {349 Executive::finalize_block()350 }351352 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {353 data.create_extrinsics()354 }355356 fn check_inherents(357 block: Block,358 data: sp_inherents::InherentData,359 ) -> sp_inherents::CheckInherentsResult {360 data.check_extrinsics(&block)361 }362363 364 365 366 }367368 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {369 fn validate_transaction(370 source: TransactionSource,371 tx: <Block as BlockT>::Extrinsic,372 hash: <Block as BlockT>::Hash,373 ) -> TransactionValidity {374 Executive::validate_transaction(source, tx, hash)375 }376 }377378 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {379 fn offchain_worker(header: &<Block as BlockT>::Header) {380 Executive::offchain_worker(header)381 }382 }383384 impl fp_rpc::EthereumRuntimeRPCApi<Block> for Runtime {385 fn chain_id() -> u64 {386 <Runtime as pallet_evm::Config>::ChainId::get()387 }388389 fn account_basic(address: H160) -> EVMAccount {390 EVM::account_basic(&address)391 }392393 fn gas_price() -> U256 {394 <Runtime as pallet_evm::Config>::FeeCalculator::min_gas_price()395 }396397 fn account_code_at(address: H160) -> Vec<u8> {398 EVM::account_codes(address)399 }400401 fn author() -> H160 {402 <pallet_evm::Pallet<Runtime>>::find_author()403 }404405 fn storage_at(address: H160, index: U256) -> H256 {406 let mut tmp = [0u8; 32];407 index.to_big_endian(&mut tmp);408 EVM::account_storages(address, H256::from_slice(&tmp[..]))409 }410411 #[allow(clippy::redundant_closure)]412 fn call(413 from: H160,414 to: H160,415 data: Vec<u8>,416 value: U256,417 gas_limit: U256,418 max_fee_per_gas: Option<U256>,419 max_priority_fee_per_gas: Option<U256>,420 nonce: Option<U256>,421 estimate: bool,422 access_list: Option<Vec<(H160, Vec<H256>)>>,423 ) -> Result<pallet_evm::CallInfo, sp_runtime::DispatchError> {424 let config = if estimate {425 let mut config = <Runtime as pallet_evm::Config>::config().clone();426 config.estimate = true;427 Some(config)428 } else {429 None430 };431432 let is_transactional = false;433 <Runtime as pallet_evm::Config>::Runner::call(434 CrossAccountId::from_eth(from),435 to,436 data,437 value,438 gas_limit.low_u64(),439 max_fee_per_gas,440 max_priority_fee_per_gas,441 nonce,442 access_list.unwrap_or_default(),443 is_transactional,444 config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),445 ).map_err(|err| err.into())446 }447448 #[allow(clippy::redundant_closure)]449 fn create(450 from: H160,451 data: Vec<u8>,452 value: U256,453 gas_limit: U256,454 max_fee_per_gas: Option<U256>,455 max_priority_fee_per_gas: Option<U256>,456 nonce: Option<U256>,457 estimate: bool,458 access_list: Option<Vec<(H160, Vec<H256>)>>,459 ) -> Result<pallet_evm::CreateInfo, sp_runtime::DispatchError> {460 let config = if estimate {461 let mut config = <Runtime as pallet_evm::Config>::config().clone();462 config.estimate = true;463 Some(config)464 } else {465 None466 };467468 let is_transactional = false;469 <Runtime as pallet_evm::Config>::Runner::create(470 CrossAccountId::from_eth(from),471 data,472 value,473 gas_limit.low_u64(),474 max_fee_per_gas,475 max_priority_fee_per_gas,476 nonce,477 access_list.unwrap_or_default(),478 is_transactional,479 config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),480 ).map_err(|err| err.into())481 }482483 fn current_transaction_statuses() -> Option<Vec<TransactionStatus>> {484 Ethereum::current_transaction_statuses()485 }486487 fn current_block() -> Option<pallet_ethereum::Block> {488 Ethereum::current_block()489 }490491 fn current_receipts() -> Option<Vec<pallet_ethereum::Receipt>> {492 Ethereum::current_receipts()493 }494495 fn current_all() -> (496 Option<pallet_ethereum::Block>,497 Option<Vec<pallet_ethereum::Receipt>>,498 Option<Vec<TransactionStatus>>499 ) {500 (501 Ethereum::current_block(),502 Ethereum::current_receipts(),503 Ethereum::current_transaction_statuses()504 )505 }506507 fn extrinsic_filter(xts: Vec<<Block as sp_api::BlockT>::Extrinsic>) -> Vec<pallet_ethereum::Transaction> {508 xts.into_iter().filter_map(|xt| match xt.0.function {509 Call::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction),510 _ => None511 }).collect()512 }513514 fn elasticity() -> Option<Permill> {515 None516 }517 }518519 impl fp_rpc::ConvertTransactionRuntimeApi<Block> for Runtime {520 fn convert_transaction(transaction: pallet_ethereum::Transaction) -> <Block as BlockT>::Extrinsic {521 UncheckedExtrinsic::new_unsigned(522 pallet_ethereum::Call::<Runtime>::transact { transaction }.into(),523 )524 }525 }526527 impl sp_session::SessionKeys<Block> for Runtime {528 fn decode_session_keys(529 encoded: Vec<u8>,530 ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {531 SessionKeys::decode_into_raw_public_keys(&encoded)532 }533534 fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {535 SessionKeys::generate(seed)536 }537 }538539 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {540 fn slot_duration() -> sp_consensus_aura::SlotDuration {541 sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())542 }543544 fn authorities() -> Vec<AuraId> {545 Aura::authorities().to_vec()546 }547 }548549 impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {550 fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {551 ParachainSystem::collect_collation_info(header)552 }553 }554555 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {556 fn account_nonce(account: AccountId) -> Index {557 System::account_nonce(account)558 }559 }560561 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {562 fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {563 TransactionPayment::query_info(uxt, len)564 }565 fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<Balance> {566 TransactionPayment::query_fee_details(uxt, len)567 }568 }569570 571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611 #[cfg(feature = "runtime-benchmarks")]612 impl frame_benchmarking::Benchmark<Block> for Runtime {613 fn benchmark_metadata(extra: bool) -> (614 Vec<frame_benchmarking::BenchmarkList>,615 Vec<frame_support::traits::StorageInfo>,616 ) {617 use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList};618 use frame_support::traits::StorageInfoTrait;619620 let mut list = Vec::<BenchmarkList>::new();621622 list_benchmark!(list, extra, pallet_evm_migration, EvmMigration);623 list_benchmark!(list, extra, pallet_unique, Unique);624 list_benchmark!(list, extra, pallet_structure, Structure);625 list_benchmark!(list, extra, pallet_inflation, Inflation);626 list_benchmark!(list, extra, pallet_fungible, Fungible);627 list_benchmark!(list, extra, pallet_refungible, Refungible);628 list_benchmark!(list, extra, pallet_nonfungible, Nonfungible);629 630631 let storage_info = AllPalletsReversedWithSystemFirst::storage_info();632633 return (list, storage_info)634 }635636 fn dispatch_benchmark(637 config: frame_benchmarking::BenchmarkConfig638 ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {639 use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};640641 let allowlist: Vec<TrackedStorageKey> = vec![642 643 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),644 645 hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),646 647 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),648 649 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),650 651 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),652653 654 hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a").to_vec().into(),655 ];656657 let mut batches = Vec::<BenchmarkBatch>::new();658 let params = (&config, &allowlist);659660 add_benchmark!(params, batches, pallet_evm_migration, EvmMigration);661 add_benchmark!(params, batches, pallet_unique, Unique);662 add_benchmark!(params, batches, pallet_structure, Structure);663 add_benchmark!(params, batches, pallet_inflation, Inflation);664 add_benchmark!(params, batches, pallet_fungible, Fungible);665 add_benchmark!(params, batches, pallet_refungible, Refungible);666 add_benchmark!(params, batches, pallet_nonfungible, Nonfungible);667 668669 if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }670 Ok(batches)671 }672 }673674 #[cfg(feature = "try-runtime")]675 impl frame_try_runtime::TryRuntime<Block> for Runtime {676 fn on_runtime_upgrade() -> (Weight, Weight) {677 log::info!("try-runtime::on_runtime_upgrade unique-chain.");678 let weight = Executive::try_runtime_upgrade().unwrap();679 (weight, RuntimeBlockWeights::get().max_block)680 }681682 fn execute_block_no_check(block: Block) -> Weight {683 Executive::execute_block_no_check(block)684 }685 }686 }687 }688}