-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
impl_runtime_api!
macro wrapper (#21)
* Construct runtime macro --------- Signed-off-by: Nikita Khateev <nikita.khateev@openzeppelin.com> Co-authored-by: Özgün Özerk <ozgunozerk.elo@gmail.com>
- Loading branch information
1 parent
89023af
commit eeda2d7
Showing
19 changed files
with
1,982 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "openzeppelin-polkadot-wrappers-proc" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
name = "openzeppelin_polkadot_wrappers_proc" | ||
path = "src/lib.rs" | ||
proc-macro = true | ||
|
||
[dependencies] | ||
openzeppelin-polkadot-wrappers = { path = "../" } | ||
darling = "0.20.10" | ||
proc-macro2 = "1.0.87" | ||
quote = "1.0.37" | ||
syn = "2.0.79" | ||
|
||
[features] | ||
async-backing = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
## OpenZeppelin Wrappers procedural macros | ||
|
||
### `construct_runtime!` | ||
|
||
We have made a wrapper over the `construct_runtime!` to support the abstractions. The macro itself have changed, supporting both abstractions and regular pallets: | ||
|
||
```rust | ||
#[openzeppelin_construct_runtime] | ||
mod runtime { | ||
#[abstraction] | ||
struct System; // Available names are System, Consensus, XCM, Assets, Governance, EVM. | ||
#[pallet] | ||
type Pallet = pallet_crate; // It mimics the second version of construct runtime macro, but without the pallet_index assignment | ||
} | ||
``` | ||
|
||
Pallet index assignment is hidden from this API. If you want to use it, please create an issue. | ||
|
||
#### Supported abstractions: | ||
|
||
* `System` -- `frame_system`, `pallet_timestamp`, `parachain_info`, `pallet_scheduler`, `pallet_preimage`, `pallet_proxy`, `pallet_balances`, `pallet_utility`, `cumulus_pallet_parachain_system`, `pallet_multisig`, `pallet_session` | ||
* `Assets` -- `pallet_assets`, `pallet_transaction_payment`, `pallet_asset_manager` | ||
* `Consensus` -- `pallet_authorship`, `pallet_aura`, `cumulus_pallet_aura_ext`, `pallet_collator_selection` | ||
* `Governance` -- `pallet_sudo`, `pallet_treasury`, `pallet_conviction_voting`, `pallet_whitelist`, `pallet_custom_origins`, `pallet_referenda` | ||
* `XCM` -- `pallet_message_queue`, `cumulus_pallet_xcmp_queue`, `pallet_xcm`, `cumulus_pallet_xcm`, `pallet_xcm_transactor`, `orml_xtokens`, `pallet_xcm_weight_trader` | ||
* `EVM` -- `pallet_ethereum`, `pallet_evm`, `pallet_base_fee`, `pallet_evm_chain_id` | ||
|
||
### `impl_runtime_apis!` | ||
|
||
We have also made a wrapper for `impl_runtime_apis!` macro. There is now a new macro where you only provide the types and structs: | ||
|
||
```rust | ||
#[openzeppelin_runtime_apis] | ||
mod apis { | ||
// these types should be present and required for all abstractions | ||
// runtime generated by construct_runtime | ||
type Runtime = Runtime; | ||
// block type | ||
type Block = Block; | ||
|
||
#[abstraction] | ||
mod assets { | ||
type TransactionPayment = TransactionPayment; | ||
type RuntimeCall = RuntimeCall; | ||
type Balance = Balance; | ||
} | ||
|
||
// Any impl block can also go there | ||
} | ||
``` | ||
|
||
Supported abstractions: | ||
|
||
| Abstraction name | Implemented APIs | Required configs | | ||
|---|---|---| | ||
| `EVM` | * `fp_rpc::EthereumRuntimeRPCApi`<br>* `fp_rpc::ConvertTransactionRuntimeApi` | * `RuntimeCall` -- runtime call generated by `construct_runtime` macro<br>* `Executive` -- `frame_executive::Executive` specification used by parachain system<br>* `Ethereum` -- `pallet_ethereum` pallet struct generated by `construct_runtime` macro | | ||
| `assets` | * `pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi`<br>* `pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi` | * `TransactionPayment` -- `pallet_transaction_payment` struct pallet generated by `construct_runtime` macro<br> * `RuntimeCall` -- runtime call generated by `construct_runtime` macro<br> * `Balance` -- type used for balance specification (e.g. in `pallet_balances` config) | | ||
| `consensus` | * `sp_consensus_aura::AuraApi`<br> * `sp_session::SessionKeys`<br> * `cumulus_primitives_aura::AuraUnincludedSegmentApi` (if `async-backing` feature is enabled) | * `SessionKeys` -- struct generated by `impl_opaque_keys` macro <br> * `Aura` -- `pallet_aura` struct pallet generated by `construct_runtime` macro (only if `async-backing` feature is not enabled)<br> * `SlotDuration` -- constant that is use for slot duration definition (only if `async-backing` feature is enabled)<br> * `ConsensusHook` -- type that is used in `cumulus_pallet_parachain_system::Config::ConsensusHook` (only if `async-backing` feature is enabled) | | ||
| `system` | * `sp_api::Core`<br> * `sp_api::Metadata`<br> * `sp_block_builder::BlockBuilder`<br> * `sp_transaction_pool::runtime_api::TaggedTransactionQueue` <br> * `sp_offchain::OffchainWorkerApi` <br> * `frame_system_rpc_runtime_api::AccountNonceApi` <br> * `cumulus_primitives_core::CollectCollationInfo` <br> * `frame_try_runtime::TryRuntime` (under a `try-runtime` feature) <br> * `sp_genesis_builder::GenesisBuilder` | * `Executive` -- `frame_executive::Executive` specification used by parachain system<br> * `System` -- `frame_system` pallet struct generated by `construct_runtime` macro<br> * `ParachainSystem` -- `cumulus_pallet_parachain_system` pallet struct generated by `construct_runtime` macro<br> * `RuntimeVersion` -- runtime version, generated by `sp_version::runtime_version`<br> * `AccountId` -- account id type that was specified in `frame_system::Config`<br> * `Nonce` -- nonce type that was specified in `frame_system::Config`<br> * `RuntimeGenesisConfig` -- type generated by `construct_runtime` macro.<br> * `RuntimeBlockWeights` -- type implementing `Get<BlockWeights>`, often built by `BlockWeights::builder` | | ||
| `benchmarks` | * `frame_benchmarking::Benchmark` (under `runtime-benchmarks` feature) | * `Assets` -- `palet_assets` pallet struct generated by `construct_runtime` macro<br> * `AssetManager` -- `pallet_asset_manager` pallet struct generated by `construct_runtime` macro<br> * `AssetType` -- struct that describes foreign assets in XCM configuration (e.g. the one that was passed to `AssetType` field in `AssetsConfig`)<br> * `RuntimeOrigin` -- type generated by `construct_runtime` macro<br> * `RelayLocation` -- `Location` type pointing to the relaychain.<br> * `System` -- `frame_system` pallet struct generated by `construct_runtime` macro<br> * `ParachainSystem` -- `cumulus_pallet_parachain_system` pallet struct generated by `construct_runtime` macro<br> * `ExistentialDeposit` -- type that describes existential deposit (e.g. the one passed to `SystemConfig`)<br> * `AssetId` -- type that describes internal asset id (e.g `AssetId` passet to `AssetsConfig`)<br> * `XCMConfig` -- struct that implements `xcm_executor::Config`. If you are using pallet abstractions it is generated by XCM abstraction and called `XcmExecutorConfig`<br> * `AccountId` -- account id type that was specified in `frame_system::Config`<br> * `Cents` -- constant that represents 1/100 of your native token.<br> * `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`. <br> * `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.<br> * `Address` -- type that describes address format for describing accounts.</br> * `Balances` -- `pallet_balances` pallet struct generated by `construct_runtime` macro | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use proc_macro2::TokenStream; | ||
use quote::quote; | ||
use syn::{Ident, Item}; | ||
|
||
use super::fetch_ident; | ||
|
||
#[derive(Debug)] | ||
pub struct AssetAPIFields { | ||
pub transaction_payment: Ident, | ||
pub balance: Ident, | ||
pub call: Ident, | ||
} | ||
|
||
impl TryFrom<&[Item]> for AssetAPIFields { | ||
type Error = &'static str; | ||
fn try_from(value: &[Item]) -> Result<Self, Self::Error> { | ||
let mut transaction_payment = None; | ||
let mut call = None; | ||
let mut balance = None; | ||
|
||
for item in value { | ||
if let Item::Type(ty) = item { | ||
if ty.ident == "TransactionPayment" { | ||
transaction_payment = Some(fetch_ident(&ty.ty)) | ||
} else if ty.ident == "RuntimeCall" { | ||
call = Some(fetch_ident(&ty.ty)) | ||
} else if ty.ident == "Balance" { | ||
balance = Some(fetch_ident(&ty.ty)) | ||
} | ||
} | ||
} | ||
|
||
let transaction_payment = | ||
transaction_payment.ok_or("`type TransactionPayment` not specified, but required")?; | ||
let balance = balance.ok_or("`type Balance` not specified, but required")?; | ||
let call = call.ok_or("`type RuntimeCall` not specified, but required")?; | ||
Ok(AssetAPIFields { | ||
transaction_payment, | ||
balance, | ||
call, | ||
}) | ||
} | ||
} | ||
|
||
pub fn assets_apis( | ||
runtime: &Ident, | ||
block: &Ident, | ||
transaction_payment: &Ident, | ||
balance: &Ident, | ||
call: &Ident, | ||
) -> TokenStream { | ||
quote! { | ||
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<#block, #balance> | ||
for #runtime | ||
{ | ||
fn query_info( | ||
uxt: <#block as sp_runtime::traits::Block>::Extrinsic, | ||
len: u32, | ||
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<#balance> { | ||
#transaction_payment::query_info(uxt, len) | ||
} | ||
fn query_fee_details( | ||
uxt: <#block as sp_runtime::traits::Block>::Extrinsic, | ||
len: u32, | ||
) -> pallet_transaction_payment::FeeDetails<#balance> { | ||
#transaction_payment::query_fee_details(uxt, len) | ||
} | ||
fn query_weight_to_fee(weight: frame_support::weights::Weight) -> #balance { | ||
#transaction_payment::weight_to_fee(weight) | ||
} | ||
fn query_length_to_fee(length: u32) -> #balance { | ||
#transaction_payment::length_to_fee(length) | ||
} | ||
} | ||
|
||
impl | ||
pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi< | ||
#block, | ||
#balance, | ||
#call, | ||
> for #runtime | ||
{ | ||
fn query_call_info( | ||
call: #call, | ||
len: u32, | ||
) -> pallet_transaction_payment::RuntimeDispatchInfo<#balance> { | ||
#transaction_payment::query_call_info(call, len) | ||
} | ||
fn query_call_fee_details( | ||
call: #call, | ||
len: u32, | ||
) -> pallet_transaction_payment::FeeDetails<#balance> { | ||
#transaction_payment::query_call_fee_details(call, len) | ||
} | ||
fn query_weight_to_fee(weight: frame_support::weights::Weight) -> #balance { | ||
#transaction_payment::weight_to_fee(weight) | ||
} | ||
fn query_length_to_fee(length: u32) -> #balance { | ||
#transaction_payment::length_to_fee(length) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.