diff --git a/procedural/README.md b/procedural/README.md
index e835ded..09a494a 100644
--- a/procedural/README.md
+++ b/procedural/README.md
@@ -56,6 +56,7 @@ Supported abstractions:
| `EVM` | * `fp_rpc::EthereumRuntimeRPCApi`
* `fp_rpc::ConvertTransactionRuntimeApi` | * `RuntimeCall` -- runtime call generated by `construct_runtime` macro
* `Executive` -- `frame_executive::Executive` specification used by parachain system
* `Ethereum` -- `pallet_ethereum` pallet struct generated by `construct_runtime` macro |
| `assets` | * `pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi`
* `pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi` | * `TransactionPayment` -- `pallet_transaction_payment` struct pallet generated by `construct_runtime` macro
* `RuntimeCall` -- runtime call generated by `construct_runtime` macro
* `Balance` -- type used for balance specification (e.g. in `pallet_balances` config) |
| `consensus` | * `sp_consensus_aura::AuraApi`
* `sp_session::SessionKeys`
* `cumulus_primitives_aura::AuraUnincludedSegmentApi` (if `async-backing` feature is enabled) | * `SessionKeys` -- struct generated by `impl_opaque_keys` macro
* `Aura` -- `pallet_aura` struct pallet generated by `construct_runtime` macro (only if `async-backing` feature is not enabled)
* `SlotDuration` -- constant that is use for slot duration definition (only if `async-backing` feature is enabled)
* `ConsensusHook` -- type that is used in `cumulus_pallet_parachain_system::Config::ConsensusHook` (only if `async-backing` feature is enabled) |
-| `system` | * `sp_api::Core`
* `sp_api::Metadata`
* `sp_block_builder::BlockBuilder`
* `sp_transaction_pool::runtime_api::TaggedTransactionQueue`
* `sp_offchain::OffchainWorkerApi`
* `frame_system_rpc_runtime_api::AccountNonceApi`
* `cumulus_primitives_core::CollectCollationInfo`
* `frame_try_runtime::TryRuntime` (under a `try-runtime` feature)
* `sp_genesis_builder::GenesisBuilder`
* `frame_system_benchmarking::Config` (under a `runtime-benchmarks` feature) | * `Executive` -- `frame_executive::Executive` specification used by parachain system
* `System` -- `frame_system` pallet struct generated by `construct_runtime` macro
* `ParachainSystem` -- `cumulus_pallet_parachain_system` pallet struct generated by `construct_runtime` macro
* `RuntimeVersion` -- runtime version, generated by `sp_version::runtime_version`
* `AccountId` -- account id type that was specified in `frame_system::Config`
* `Nonce` -- npnce type that was specified in `frame_system::Config`
* `RuntimeGenesisBuilder` -- type generated by `construct_runtime` macro. |
+| `system` | * `sp_api::Core`
* `sp_api::Metadata`
* `sp_block_builder::BlockBuilder`
* `sp_transaction_pool::runtime_api::TaggedTransactionQueue`
* `sp_offchain::OffchainWorkerApi`
* `frame_system_rpc_runtime_api::AccountNonceApi`
* `cumulus_primitives_core::CollectCollationInfo`
* `frame_try_runtime::TryRuntime` (under a `try-runtime` feature)
* `sp_genesis_builder::GenesisBuilder`
* `frame_system_benchmarking::Config` (under a `runtime-benchmarks` feature) | * `Executive` -- `frame_executive::Executive` specification used by parachain system
* `System` -- `frame_system` pallet struct generated by `construct_runtime` macro
* `ParachainSystem` -- `cumulus_pallet_parachain_system` pallet struct generated by `construct_runtime` macro
* `RuntimeVersion` -- runtime version, generated by `sp_version::runtime_version`
* `AccountId` -- account id type that was specified in `frame_system::Config`
* `Nonce` -- nonce type that was specified in `frame_system::Config`
* `RuntimeGenesisBuilder` -- type generated by `construct_runtime` macro. |
+| `benchmarks` | * `frame_benchmarking::Benchmark` (under `runtime-benchmarks` feature) | * `Assets` -- `palet_assets` pallet struct generated by `construct_runtime` macro
* `AssetManager` -- `pallet_asset_manager` pallet struct generated by `construct_runtime` macro
* `AssetType` -- struct that describes foreign assets in XCM configuration (e.g. the one that was passed to `AssetType` field in `AssetsConfig`
* `RuntimeOrigin` -- type generated by `construct_runtime` macro
* `RelayLocation` -- `Location` type pointing to the relaychain.
* `ParachainSystem` -- `cumulus_pallet_parachain_system` pallet struct generated by `construct_runtime` macro
* `ExistentialDeposit` -- type that decribes existential deposit (e.g. the one passed to `SystemConfig`)
* `AssetId` -- type that describes internal asset id (e.g `AssetId` passet to `AssetsConfig`)
* `XCMConfig` -- struct that implements `xcm_executor::Config`. If you are using pallet abstractions it is generated by XCM abstraction and called `XcmExecutorConfig`
* `AccountId` -- account id type that was specified in `frame_system::Config`
* `Cents` -- constant that represents 1/100 of your native token.
* `FeeAssetId` -- type that describes an asset to pay XCM fees in. If you used an abstraction macro for XCM support, it was generated along the way and named `FeeAssetId`.
* `TransactionByteFee` -- type that describes fee per byte of data. If you used an abstraction macro for assets support it was generated with the same name.|
Also, this macro implements `frame_benchmarking::Benchmark` for all of the specified pallets.
\ No newline at end of file
diff --git a/procedural/src/apis/benchmark.rs b/procedural/src/apis/benchmark.rs
index a7fc212..b02c104 100644
--- a/procedural/src/apis/benchmark.rs
+++ b/procedural/src/apis/benchmark.rs
@@ -1,31 +1,214 @@
+use proc_macro2::Ident;
use quote::quote;
+use syn::Item;
+
+use super::fetch_ident;
#[derive(Default)]
pub struct AbstractionState {
- pub assets: bool,
- pub xcm: bool,
+ pub benchmark_fields: Option,
pub consensus: bool,
}
-pub fn construct_benchmarking_api(state: AbstractionState) -> proc_macro2::TokenStream {
+pub struct BenchmarkAPIFields {
+ pub all_pallets_with_system: Ident,
+ pub xcm_fields: Option,
+}
+
+impl TryFrom<&[Item]> for BenchmarkAPIFields {
+ type Error = &'static str;
+
+ fn try_from(value: &[Item]) -> Result {
+ let mut all_pallets_with_system = None;
+
+ for item in value {
+ match item {
+ Item::Type(ty) => {
+ if ty.ident == "AllPalletsWithSystem" {
+ all_pallets_with_system = Some(fetch_ident(&ty.ty))
+ }
+ }
+ _ => (),
+ }
+ }
+
+ let all_pallets_with_system = all_pallets_with_system
+ .ok_or("type `AllPalletsWithSystem` not specified, but required")?;
+ let xcm_fields = XCMBenchmarkAPIFields::try_from(value)
+ .map_err(|e| println!("{e:?}"))
+ .ok();
+
+ Ok(BenchmarkAPIFields {
+ all_pallets_with_system,
+ xcm_fields,
+ })
+ }
+}
+
+pub struct XCMBenchmarkAPIFields {
+ pub assets: Ident,
+ pub asset_manager: Ident,
+ pub asset_type: Ident,
+ pub runtime_origin: Ident,
+ pub relay_location: Ident,
+ pub parachain_system: Ident,
+ pub existential_deposit: Ident,
+ pub asset_id: Ident,
+ pub xcm_config: Ident,
+ pub account_id: Ident,
+ pub cents: Ident,
+ pub fee_asset_id: Ident,
+ pub transaction_byte_fee: Ident,
+}
+
+impl TryFrom<&[Item]> for XCMBenchmarkAPIFields {
+ type Error = &'static str;
+ fn try_from(value: &[Item]) -> Result {
+ let mut assets = None;
+ let mut asset_manager = None;
+ let mut asset_type = None;
+ let mut runtime_origin = None;
+ let mut relay_location = None;
+ let mut parachain_system = None;
+ let mut existential_deposit = None;
+ let mut asset_id = None;
+ let mut xcm_config = None;
+ let mut account_id = None;
+ let mut cents = None;
+ let mut fee_asset_id = None;
+ let mut transaction_byte_fee = None;
+
+ for item in value {
+ match item {
+ Item::Type(ty) => {
+ if ty.ident == "Assets" {
+ assets = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "AssetManager" {
+ asset_manager = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "AssetType" {
+ asset_type = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "RuntimeOrigin" {
+ runtime_origin = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "RelayLocation" {
+ relay_location = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "ParachainSystem" {
+ parachain_system = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "ExistentialDeposit" {
+ existential_deposit = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "AssetId" {
+ asset_id = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "XCMConfig" {
+ xcm_config = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "AccountId" {
+ account_id = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "Cents" {
+ cents = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "FeeAssetId" {
+ fee_asset_id = Some(fetch_ident(&ty.ty))
+ } else if ty.ident == "TransactionByteFee" {
+ transaction_byte_fee = Some(fetch_ident(&ty.ty))
+ }
+ }
+ _ => (),
+ }
+ }
+
+ let assets = assets.ok_or("type `Assets` not specified, but required")?;
+ let asset_manager =
+ asset_manager.ok_or("type `AssetManager` not specified, but required")?;
+ let asset_type = asset_type.ok_or("type `AssetType` not specified, but required")?;
+ let runtime_origin =
+ runtime_origin.ok_or("type `RuntimeOrigin` not specified, but required")?;
+ let relay_location =
+ relay_location.ok_or("type `RelayLocation` not specified, but required")?;
+ let parachain_system =
+ parachain_system.ok_or("type `ParachainSystem` not specified, but required")?;
+ let existential_deposit =
+ existential_deposit.ok_or("type `ExistentialDeposit` not specified, but required")?;
+ let asset_id = asset_id.ok_or("type `AssetId` not specified, but required")?;
+ let xcm_config = xcm_config.ok_or("type `XCMConfig` not specified, but required")?;
+ let account_id = account_id.ok_or("type `AccountId` not specified, but required")?;
+ let cents = cents.ok_or("type `Cents` not specified, but required")?;
+ let fee_asset_id = fee_asset_id.ok_or("type `FeeAssetId` not specified, but required")?;
+ let transaction_byte_fee =
+ transaction_byte_fee.ok_or("type `TransactionByteFee` not specified, but required")?;
+
+ Ok(XCMBenchmarkAPIFields {
+ assets,
+ asset_manager,
+ asset_type,
+ runtime_origin,
+ relay_location,
+ parachain_system,
+ existential_deposit,
+ asset_id,
+ xcm_config,
+ account_id,
+ cents,
+ fee_asset_id,
+ transaction_byte_fee,
+ })
+ }
+}
+
+pub fn construct_benchmarking_api(
+ consensus_benchmarking: bool,
+ runtime: &Ident,
+ api_fields: BenchmarkAPIFields,
+) -> proc_macro2::TokenStream {
let mut xcm_dispatch = quote! {};
let mut xcm_metadata = quote! {};
let mut consensus_dispatch = quote! {};
let mut consensus_metadata = quote! {};
- if state.consensus {
- consensus_dispatch = construct_consensus_dispatch_benchmarking();
+ if consensus_benchmarking {
+ consensus_dispatch = construct_consensus_dispatch_benchmarking(runtime);
consensus_metadata = construct_consensus_metadata_benchmarking();
}
- if state.assets && state.xcm {
+ let BenchmarkAPIFields {
+ all_pallets_with_system,
+ xcm_fields,
+ } = api_fields;
+
+ if let Some(XCMBenchmarkAPIFields {
+ assets,
+ asset_manager,
+ asset_type,
+ runtime_origin,
+ relay_location,
+ parachain_system,
+ existential_deposit,
+ asset_id,
+ xcm_config,
+ account_id,
+ cents,
+ fee_asset_id,
+ transaction_byte_fee,
+ }) = xcm_fields
+ {
xcm_metadata = construct_xcm_metadata_benchmarking();
- xcm_dispatch = construct_xcm_dispatch_benchmarking();
+ xcm_dispatch = construct_xcm_dispatch_benchmarking(
+ runtime,
+ assets,
+ asset_manager,
+ asset_type,
+ runtime_origin,
+ relay_location,
+ parachain_system,
+ existential_deposit,
+ asset_id,
+ xcm_config,
+ account_id,
+ cents,
+ fee_asset_id,
+ transaction_byte_fee,
+ );
}
quote! {
#[cfg(feature = "runtime-benchmarks")]
- impl frame_benchmarking::Benchmark for Runtime {
+ impl frame_benchmarking::Benchmark for #runtime {
fn benchmark_metadata(extra: bool) -> (
Vec,
Vec,
@@ -37,12 +220,10 @@ pub fn construct_benchmarking_api(state: AbstractionState) -> proc_macro2::Token
#xcm_metadata
#consensus_metadata
- use super::*;
-
let mut list = Vec::::new();
list_benchmarks!(list, extra);
- let storage_info = AllPalletsWithSystem::storage_info();
+ let storage_info = #all_pallets_with_system::storage_info();
(list, storage_info)
}
@@ -52,13 +233,11 @@ pub fn construct_benchmarking_api(state: AbstractionState) -> proc_macro2::Token
use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch};
use frame_system_benchmarking::Pallet as SystemBench;
- use super::{*, types::*, configs::*, constants::currency::CENTS};
-
#xcm_dispatch
#consensus_dispatch
use frame_support::traits::WhitelistedStorageKeys;
- let whitelist = AllPalletsWithSystem::whitelisted_storage_keys();
+ let whitelist = #all_pallets_with_system::whitelisted_storage_keys();
let mut batches = Vec::::new();
let params = (&config, &whitelist);
@@ -77,10 +256,10 @@ fn construct_consensus_metadata_benchmarking() -> proc_macro2::TokenStream {
}
}
-fn construct_consensus_dispatch_benchmarking() -> proc_macro2::TokenStream {
+fn construct_consensus_dispatch_benchmarking(runtime: &Ident) -> proc_macro2::TokenStream {
quote! {
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
- impl cumulus_pallet_session_benchmarking::Config for Runtime {}
+ impl cumulus_pallet_session_benchmarking::Config for #runtime {}
}
}
@@ -90,31 +269,49 @@ fn construct_xcm_metadata_benchmarking() -> proc_macro2::TokenStream {
}
}
-// TODO: think how this should change if AssetManager is included
-fn construct_xcm_dispatch_benchmarking() -> proc_macro2::TokenStream {
+fn construct_xcm_dispatch_benchmarking(
+ runtime: &Ident,
+ assets: Ident,
+ asset_manager: Ident,
+ asset_type: Ident,
+ runtime_origin: Ident,
+ relay_location: Ident,
+ parachain_system: Ident,
+ existential_deposit: Ident,
+ asset_id: Ident,
+ xcm_config: Ident,
+ account_id: Ident,
+ cents: Ident,
+ fee_asset_id: Ident,
+ transaction_byte_fee: Ident,
+) -> proc_macro2::TokenStream {
quote! {
use cumulus_primitives_core::ParaId;
use frame_support::parameter_types;
+ use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
+ use xcm::latest::prelude::{Asset, AssetId as XcmAssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen, PalletInstance, GeneralIndex};
+
parameter_types! {
pub const RandomParaId: ParaId = ParaId::new(43211234);
pub ExistentialDepositAsset: Option = Some((
- RelayLocation::get(),
- ExistentialDeposit::get()
+ #relay_location::get(),
+ #existential_deposit::get()
).into());
/// The base fee for the message delivery fees. Kusama is based for the reference.
- pub const ToParentBaseDeliveryFee: u128 = CENTS.saturating_mul(3);
+ pub const ToParentBaseDeliveryFee: u128 = #cents.saturating_mul(3);
+ pub const InitialTransferAssetAmount: u128 = 4001070000100;
}
+
pub type PriceForParentDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
- FeeAssetId,
+ #fee_asset_id,
ToParentBaseDeliveryFee,
- TransactionByteFee,
- ParachainSystem,
+ #transaction_byte_fee,
+ #parachain_system,
>;
- use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
- use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen, PalletInstance, GeneralIndex};
- impl pallet_xcm::benchmarking::Config for Runtime {
+
+ impl pallet_xcm::benchmarking::Config for #runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
- xcm_config::XcmConfig,
+ #xcm_config,
ExistentialDepositAsset,
PriceForParentDelivery,
>;
@@ -129,30 +326,61 @@ fn construct_xcm_dispatch_benchmarking() -> proc_macro2::TokenStream {
fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
use frame_support::traits::PalletInfoAccess;
- ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
- RandomParaId::get().into()
+ use xcm_primitives::AssetTypeGetter;
+ use frame_system::RawOrigin;
+
+ // set up fee asset
+ let fee_location = #relay_location::get();
+ let who: #account_id = frame_benchmarking::whitelisted_caller();
+
+ let Some(location_v3) = xcm::v3::Location::try_from(fee_location.clone()).ok() else {
+ return None;
+ };
+ let asset_type = #asset_type::Xcm(location_v3);
+
+ let local_asset_id: #asset_id = asset_type.clone().into();
+ let manager_id = #asset_manager::account_id();
+ let _ = #assets::force_create(#runtime_origin::root(), local_asset_id.clone().into(), sp_runtime::MultiAddress::Id(manager_id.clone()), true, 1);
+ let _ = #assets::mint(
+ RawOrigin::Signed(manager_id.clone()).into(),
+ local_asset_id.into(),
+ sp_runtime::MultiAddress::Id(who),
+ InitialTransferAssetAmount::get(),
);
- let balance = 3001070000000;
- let who = frame_benchmarking::whitelisted_caller();
- let _ =
- >::make_free_balance_be(&who, balance);
+ #asset_manager::set_asset_type_asset_id(asset_type.clone(), local_asset_id.into());
- let asset_amount: u128 = 10u128;
- let initial_asset_amount: u128 = asset_amount * 10;
+ // open a mock parachain channel
+ #parachain_system::open_outbound_hrmp_channel_for_benchmarks_or_tests(
+ RandomParaId::get().into()
+ );
+ // set up transfer asset
+ let initial_asset_amount: u128 = InitialTransferAssetAmount::get();
let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
- Runtime,
+ #runtime,
()
>(true, initial_asset_amount);
- let asset_id_u32: u32 = asset_id.into();
+ let asset_id_u128: u128 = asset_id.into();
+ let self_reserve = Location {
+ parents: 0,
+ interior: [
+ PalletInstance(<#assets as PalletInfoAccess>::index() as u8), GeneralIndex(asset_id_u128)
+ ].into()
+ };
+
+ let Some(location_v3) = xcm::v3::Location::try_from(self_reserve.clone()).ok() else {
+ return None;
+ };
+ let asset_type = #asset_type::Xcm(location_v3);
+ #asset_manager::set_asset_type_asset_id(asset_type.clone(), asset_id_u128);
- let location = Location {parents: 0, interior: (PalletInstance(::index() as u8), GeneralIndex(asset_id_u32 as u128)).into()};
+ let asset = Asset {
+ fun: Fungible(#existential_deposit::get()),
+ id: XcmAssetId(self_reserve.into())
+ }.into();
Some((
- Asset {
- fun: Fungible(ExistentialDeposit::get()),
- id: AssetId(location.into())
- }.into(),
+ asset,
ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
))
}
@@ -160,55 +388,69 @@ fn construct_xcm_dispatch_benchmarking() -> proc_macro2::TokenStream {
fn set_up_complex_asset_transfer(
) -> Option<(AssetList, u32, Location, Box)> {
use frame_support::traits::PalletInfoAccess;
+ use xcm_primitives::AssetTypeGetter;
// set up local asset
- let asset_amount: u128 = 10u128;
let initial_asset_amount: u128 = 1000000011;
+
let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
- Runtime,
+ #runtime,
()
>(true, initial_asset_amount);
- let asset_id_u32: u32 = asset_id.into();
+
+ let asset_id_u128: u128 = asset_id.into();
let self_reserve = Location {
parents:0,
interior: [
- PalletInstance(::index() as u8), GeneralIndex(asset_id_u32 as u128)
+ PalletInstance(<#assets as PalletInfoAccess>::index() as u8), GeneralIndex(asset_id_u128)
].into()
};
+ let Some(location_v3) = xcm::v3::Location::try_from(self_reserve.clone()).ok() else {
+ return None;
+ };
+ let asset_type = #asset_type::Xcm(location_v3);
+ #asset_manager::set_asset_type_asset_id(asset_type.clone(), asset_id_u128);
+
let destination: xcm::v4::Location = Parent.into();
- let fee_amount: u128 = ::ExistentialDeposit::get();
+ // set up fee asset
+ let fee_amount: u128 = <#runtime as pallet_balances::Config>::ExistentialDeposit::get();
+ let asset_amount: u128 = 10;
let fee_asset: Asset = (self_reserve.clone(), fee_amount).into();
-
- // Give some multiple of transferred amount
- let balance = fee_amount * 1000;
- let who = frame_benchmarking::whitelisted_caller();
- let _ =
- >::make_free_balance_be(&who, balance);
-
- // verify initial balance
- assert_eq!(Balances::free_balance(&who), balance);
let transfer_asset: Asset = (self_reserve.clone(), asset_amount).into();
let assets: cumulus_primitives_core::Assets = vec![fee_asset.clone(), transfer_asset].into();
let fee_index: u32 = 0;
+ let who = frame_benchmarking::whitelisted_caller();
+
let verify: Box = Box::new(move || {
// verify balance after transfer, decreased by
// transferred amount (and delivery fees)
- assert!(Assets::balance(asset_id_u32, &who) <= initial_asset_amount - fee_amount);
+ assert!(#assets::balance(asset_id_u128, &who) <= initial_asset_amount - fee_amount);
});
Some((assets, fee_index, destination, verify))
}
fn get_asset() -> Asset {
- use frame_support::traits::PalletInfoAccess;
- Asset {
- id: AssetId((Location {parents: 0, interior: (PalletInstance(::index() as u8), GeneralIndex(1)).into()}).into()),
- fun: Fungible(ExistentialDeposit::get()),
- }
+ use xcm_primitives::AssetTypeGetter;
+ let location = Location::parent();
+ let asset_id = XcmAssetId(location.clone());
+ let asset = Asset {
+ id: asset_id.clone(),
+ fun: Fungible(#existential_deposit::get()),
+ };
+ let Some(location_v3) = xcm::v3::Location::try_from(location).ok() else {
+ return asset;
+ };
+ let asset_type = #asset_type::Xcm(location_v3);
+ let local_asset_id: #asset_id = asset_type.clone().into();
+ let manager_id = #asset_manager::account_id();
+ let _ = #assets::force_create(#runtime_origin::root(), local_asset_id.clone().into(), sp_runtime::MultiAddress::Id(manager_id), true, 1);
+ #asset_manager::set_asset_type_asset_id(asset_type.clone(), local_asset_id);
+ asset
}
}
}
diff --git a/procedural/src/apis/consensus.rs b/procedural/src/apis/consensus.rs
index 64ff170..863c3aa 100644
--- a/procedural/src/apis/consensus.rs
+++ b/procedural/src/apis/consensus.rs
@@ -45,26 +45,26 @@ impl TryFrom<&[Item]> for ConsensusAPIFields {
if ty.ident == "SlotDuration" {
slot_duration = Some(fetch_ident(&typ))
} else if ty.ident == "ConsensusHook" {
- slot_duration = Some(fetch_ident(&typ))
+ consensus_hook = Some(fetch_ident(&typ))
}
}
_ => (),
}
}
- let session_keys = session_keys.ok_or("type SessionKeys` not specified, but required")?;
+ let session_keys = session_keys.ok_or("type `SessionKeys` not specified, but required")?;
#[cfg(not(feature = "async-backing"))]
{
- let aura = aura.ok_or("type Aura` not specified, but required")?;
+ let aura = aura.ok_or("type `Aura` not specified, but required")?;
Ok(ConsensusAPIFields { session_keys, aura })
}
#[cfg(feature = "async-backing")]
{
let slot_duration =
- slot_duration.ok_or("type SlotDuration` not specified, but required")?;
+ slot_duration.ok_or("type `SlotDuration` not specified, but required")?;
let consensus_hook =
- consensus_hook.ok_or("type SlotDuration` not specified, but required")?;
+ consensus_hook.ok_or("type `ConsensusHook` not specified, but required")?;
Ok(ConsensusAPIFields {
session_keys,
slot_duration,
@@ -84,14 +84,16 @@ pub fn consensus_apis(
) -> TokenStream {
#[cfg(feature = "async-backing")]
let slot_duration = quote! {
- return sp_consensus_aura::SlotDuration::from_millis(<#api_ident as SystemAPI>::SLOT_DURATION);
+ return sp_consensus_aura::SlotDuration::from_millis(#slot_duration);
};
#[cfg(not(feature = "async-backing"))]
let slot_duration = quote! {
sp_consensus_aura::SlotDuration::from_millis(#aura::slot_duration())
};
- let res = quote! {
+ let mut res = quote! {};
+
+ res.extend(quote! {
impl sp_consensus_aura::AuraApi<#block, AuraId> for #runtime {
fn slot_duration() -> sp_consensus_aura::SlotDuration {
#slot_duration
@@ -111,7 +113,7 @@ pub fn consensus_apis(
#session_keys::decode_into_raw_public_keys(&encoded)
}
}
- };
+ });
#[cfg(feature = "async-backing")]
res.extend(quote! {
impl cumulus_primitives_aura::AuraUnincludedSegmentApi<#block> for #runtime {
diff --git a/procedural/src/construct_runtime.rs b/procedural/src/construct_runtime.rs
index 4fdec7a..9e5ac78 100644
--- a/procedural/src/construct_runtime.rs
+++ b/procedural/src/construct_runtime.rs
@@ -1,4 +1,4 @@
-use crate::models::Abstractions;
+use crate::models::ConstructAbstractions;
use proc_macro::TokenStream;
use proc_macro2::{Literal, Span};
use quote::quote;
@@ -57,10 +57,10 @@ fn parse_abstraction(
item: ItemStruct,
index: &mut u32,
) -> (proc_macro2::TokenStream, Option) {
- let abstraction_name = Abstractions::try_from(item).expect("Wrong Struct");
+ let abstraction_name = ConstructAbstractions::try_from(item).expect("Wrong Struct");
match abstraction_name {
- Abstractions::System => (
+ ConstructAbstractions::System => (
construct_system(index),
Some(quote! {
cumulus_pallet_parachain_system::register_validate_block! {
@@ -69,11 +69,11 @@ fn parse_abstraction(
}
}),
),
- Abstractions::Assets => (construct_assets(index), None),
- Abstractions::Consensus => (construct_consensus(index), None),
- Abstractions::Governance => (construct_governance(index), None),
- Abstractions::XCM => (construct_xcm(index), None),
- Abstractions::EVM => (construct_evm(index), None),
+ ConstructAbstractions::Assets => (construct_assets(index), None),
+ ConstructAbstractions::Consensus => (construct_consensus(index), None),
+ ConstructAbstractions::Governance => (construct_governance(index), None),
+ ConstructAbstractions::XCM => (construct_xcm(index), None),
+ ConstructAbstractions::EVM => (construct_evm(index), None),
}
}
diff --git a/procedural/src/models.rs b/procedural/src/models.rs
index daaccdc..9725843 100644
--- a/procedural/src/models.rs
+++ b/procedural/src/models.rs
@@ -1,7 +1,7 @@
use proc_macro2::Ident;
use syn::ItemStruct;
-pub enum Abstractions {
+pub enum ConstructAbstractions {
Assets,
XCM,
EVM,
@@ -16,7 +16,7 @@ pub enum ConversionError {
NoAbstractionAttribute,
}
-impl TryFrom for Abstractions {
+impl TryFrom for ConstructAbstractions {
type Error = ConversionError;
fn try_from(value: ItemStruct) -> Result {
let is_pallet = value.attrs.iter().any(|f| {
@@ -32,25 +32,52 @@ impl TryFrom for Abstractions {
return Err(ConversionError::NoAbstractionAttribute);
}
- Abstractions::try_from(value.ident)
+ ConstructAbstractions::try_from(value.ident)
}
}
-impl TryFrom for Abstractions {
+impl TryFrom for ConstructAbstractions {
type Error = ConversionError;
fn try_from(value: Ident) -> Result {
if "Assets".eq_ignore_ascii_case(&value.to_string()) {
- Ok(Abstractions::Assets)
+ Ok(ConstructAbstractions::Assets)
} else if "XCM".eq_ignore_ascii_case(&value.to_string()) {
- Ok(Abstractions::XCM)
+ Ok(ConstructAbstractions::XCM)
} else if "EVM".eq_ignore_ascii_case(&value.to_string()) {
- Ok(Abstractions::EVM)
+ Ok(ConstructAbstractions::EVM)
} else if "System".eq_ignore_ascii_case(&value.to_string()) {
- Ok(Abstractions::System)
+ Ok(ConstructAbstractions::System)
} else if "Governance".eq_ignore_ascii_case(&value.to_string()) {
- Ok(Abstractions::Governance)
+ Ok(ConstructAbstractions::Governance)
} else if "Consensus".eq_ignore_ascii_case(&value.to_string()) {
- Ok(Abstractions::Consensus)
+ Ok(ConstructAbstractions::Consensus)
+ } else {
+ Err(ConversionError::UnknownAbstraction)
+ }
+ }
+}
+
+pub enum APIAbstractions {
+ Benchmarks,
+ System,
+ EVM,
+ Consensus,
+ Assets,
+}
+
+impl TryFrom for APIAbstractions {
+ type Error = ConversionError;
+ fn try_from(value: Ident) -> Result {
+ if "Benchmarks".eq_ignore_ascii_case(&value.to_string()) {
+ Ok(APIAbstractions::Benchmarks)
+ } else if "Assets".eq_ignore_ascii_case(&value.to_string()) {
+ Ok(APIAbstractions::Assets)
+ } else if "EVM".eq_ignore_ascii_case(&value.to_string()) {
+ Ok(APIAbstractions::EVM)
+ } else if "System".eq_ignore_ascii_case(&value.to_string()) {
+ Ok(APIAbstractions::System)
+ } else if "Consensus".eq_ignore_ascii_case(&value.to_string()) {
+ Ok(APIAbstractions::Consensus)
} else {
Err(ConversionError::UnknownAbstraction)
}
diff --git a/procedural/src/runtime_apis.rs b/procedural/src/runtime_apis.rs
index 5f937b5..d967f98 100644
--- a/procedural/src/runtime_apis.rs
+++ b/procedural/src/runtime_apis.rs
@@ -1,9 +1,9 @@
use crate::{
apis::{
- self, construct_benchmarking_api, fetch_ident, AbstractionState, AssetAPIFields,
+ self, fetch_ident, AbstractionState, AssetAPIFields, BenchmarkAPIFields,
ConsensusAPIFields, EVMAPIFields, SystemAPIFields,
},
- models::Abstractions,
+ models::APIAbstractions,
};
use core::panic;
use proc_macro::TokenStream;
@@ -34,13 +34,13 @@ pub fn impl_openzeppelin_runtime_apis(input: TokenStream) -> TokenStream {
}
Item::Mod(m) => {
let is_abstraction = m.attrs.iter().any(|f| {
- let Ok(path) = f.meta.require_path_only() else {
- return false;
- };
- let Ok(ident) = path.require_ident() else {
- return false;
- };
- ident == "abstraction"
+ let Ok(path) = f.meta.require_path_only() else {
+ return false;
+ };
+ let Ok(ident) = path.require_ident() else {
+ return false;
+ };
+ ident == "abstraction"
});
if is_abstraction {
abstractions.push(m)
@@ -71,7 +71,15 @@ pub fn impl_openzeppelin_runtime_apis(input: TokenStream) -> TokenStream {
));
}
- let benchmarks = construct_benchmarking_api(state);
+ if let AbstractionState {
+ benchmark_fields: Some(fields),
+ consensus,
+ } = state
+ {
+ inner.extend(apis::construct_benchmarking_api(
+ consensus, &runtime, fields,
+ ));
+ }
let expanded = quote! {
use sp_api::impl_runtime_apis;
@@ -92,8 +100,6 @@ pub fn impl_openzeppelin_runtime_apis(input: TokenStream) -> TokenStream {
impl_runtime_apis! {
#inner
-
- #benchmarks
}
};
@@ -106,13 +112,13 @@ fn construct_abstraction(
runtime: &Ident,
block: &Ident,
) -> proc_macro2::TokenStream {
- let abstraction = Abstractions::try_from(item.ident).expect("Wrong Abstraction Struct");
+ let abstraction = APIAbstractions::try_from(item.ident).expect("Wrong Abstraction Struct");
let (_, content) = item
.content
.expect("`mod assets` does not have any content.");
match abstraction {
- Abstractions::EVM => {
+ APIAbstractions::EVM => {
let EVMAPIFields {
call,
executive,
@@ -121,9 +127,7 @@ fn construct_abstraction(
apis::evm_apis(runtime, block, &call, &executive, ðereum)
}
- Abstractions::Assets => {
- state.assets = true;
-
+ APIAbstractions::Assets => {
let AssetAPIFields {
transaction_payment,
balance,
@@ -133,9 +137,8 @@ fn construct_abstraction(
apis::assets_apis(runtime, block, &transaction_payment, &balance, &call)
}
- Abstractions::Consensus => {
- state.assets = true;
-
+ APIAbstractions::Consensus => {
+ state.consensus = true;
#[cfg(not(feature = "async-backing"))]
{
let ConsensusAPIFields { session_keys, aura } =
@@ -160,7 +163,7 @@ fn construct_abstraction(
)
}
}
- Abstractions::System => {
+ APIAbstractions::System => {
let SystemAPIFields {
executive,
system,
@@ -184,10 +187,13 @@ fn construct_abstraction(
&genesis,
)
}
- Abstractions::XCM => {
- state.xcm = true;
+
+ APIAbstractions::Benchmarks => {
+ let api_fields = BenchmarkAPIFields::try_from(content.as_slice())
+ .expect("Error while parsing benchmarking config");
+
+ state.benchmark_fields = Some(api_fields);
quote! {}
}
- _ => quote! {},
}
}