Skip to content

Commit

Permalink
Adds instance support for composite enums (paritytech#1857)
Browse files Browse the repository at this point in the history
Fixes paritytech#1839

Currently, `composite_enum`s do not support pallet instances. This PR
allows the following:
```rust
	#[pallet::composite_enum]
	pub enum HoldReason<I: 'static = ()> {
		SomeHoldReason
	}
```

### Todo

- [x]  UI Test
  • Loading branch information
gupnik committed Oct 13, 2023
1 parent c773ce8 commit 8b127b1
Show file tree
Hide file tree
Showing 11 changed files with 264 additions and 93 deletions.
4 changes: 2 additions & 2 deletions substrate/frame/balances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ pub mod pallet {

/// The overarching hold reason.
#[pallet::no_default_bounds]
type RuntimeHoldReason: Parameter + Member + MaxEncodedLen + Ord + Copy;
type RuntimeHoldReason: Parameter + Member + MaxEncodedLen + Copy;

/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
Expand Down Expand Up @@ -300,7 +300,7 @@ pub mod pallet {
type ReserveIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy;

/// The ID type for freezes.
type FreezeIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy;
type FreezeIdentifier: Parameter + Member + MaxEncodedLen + Copy;

/// The maximum number of locks that should exist on an account.
/// Not strictly enforced, but used for weight estimation.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License

use crate::construct_runtime::parse::PalletPath;
use proc_macro2::{Ident, TokenStream};
use quote::quote;

pub(crate) fn expand_conversion_fn(
composite_name: &str,
path: &PalletPath,
instance: Option<&Ident>,
variant_name: &Ident,
) -> TokenStream {
let composite_name = quote::format_ident!("{}", composite_name);
let runtime_composite_name = quote::format_ident!("Runtime{}", composite_name);

if let Some(inst) = instance {
quote! {
impl From<#path::#composite_name<#path::#inst>> for #runtime_composite_name {
fn from(hr: #path::#composite_name<#path::#inst>) -> Self {
#runtime_composite_name::#variant_name(hr)
}
}
}
} else {
quote! {
impl From<#path::#composite_name> for #runtime_composite_name {
fn from(hr: #path::#composite_name) -> Self {
#runtime_composite_name::#variant_name(hr)
}
}
}
}
}

pub(crate) fn expand_variant(
composite_name: &str,
index: u8,
path: &PalletPath,
instance: Option<&Ident>,
variant_name: &Ident,
) -> TokenStream {
let composite_name = quote::format_ident!("{}", composite_name);

if let Some(inst) = instance {
quote! {
#[codec(index = #index)]
#variant_name(#path::#composite_name<#path::#inst>),
}
} else {
quote! {
#[codec(index = #index)]
#variant_name(#path::#composite_name),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License

use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;

pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
Expand All @@ -27,17 +28,29 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();

conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"FreezeReason",
path,
instance,
variant_name,
));

freeze_reason_variants.push(expand_variant(index, path, variant_name));
freeze_reason_variants.push(composite_helper::expand_variant(
"FreezeReason",
index,
path,
instance,
variant_name,
));
}
}

quote! {
/// A reason for placing a freeze on funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
Expand All @@ -49,20 +62,3 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
#( #conversion_fns )*
}
}

fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::FreezeReason> for RuntimeFreezeReason {
fn from(hr: #path::FreezeReason) -> Self {
RuntimeFreezeReason::#variant_name(hr)
}
}
}
}

fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::FreezeReason),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License

use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;

pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
Expand All @@ -27,17 +28,29 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();

conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"HoldReason",
path,
instance,
variant_name,
));

hold_reason_variants.push(expand_variant(index, path, variant_name));
hold_reason_variants.push(composite_helper::expand_variant(
"HoldReason",
index,
path,
instance,
variant_name,
));
}
}

quote! {
/// A reason for placing a hold on funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
Expand All @@ -49,20 +62,3 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
#( #conversion_fns )*
}
}

fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::HoldReason> for RuntimeHoldReason {
fn from(hr: #path::HoldReason) -> Self {
RuntimeHoldReason::#variant_name(hr)
}
}
}
}

fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::HoldReason),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License

use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;

pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
Expand All @@ -27,17 +28,29 @@ pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> To
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();

conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"LockId",
path,
instance,
variant_name,
));

lock_id_variants.push(expand_variant(index, path, variant_name));
lock_id_variants.push(composite_helper::expand_variant(
"LockId",
index,
path,
instance,
variant_name,
));
}
}

quote! {
/// An identifier for each lock placed on funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
Expand All @@ -49,20 +62,3 @@ pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> To
#( #conversion_fns )*
}
}

fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::LockId> for RuntimeLockId {
fn from(hr: #path::LockId) -> Self {
RuntimeLockId::#variant_name(hr)
}
}
}
}

fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::LockId),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// limitations under the License

mod call;
pub mod composite_helper;
mod config;
mod freeze_reason;
mod hold_reason;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License

use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;

pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
Expand All @@ -27,17 +28,29 @@ pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();

conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"SlashReason",
path,
instance,
variant_name,
));

slash_reason_variants.push(expand_variant(index, path, variant_name));
slash_reason_variants.push(composite_helper::expand_variant(
"SlashReason",
index,
path,
instance,
variant_name,
));
}
}

quote! {
/// A reason for slashing funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
Expand All @@ -49,20 +62,3 @@ pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
#( #conversion_fns )*
}
}

fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::SlashReason> for RuntimeSlashReason {
fn from(hr: #path::SlashReason) -> Self {
RuntimeSlashReason::#variant_name(hr)
}
}
}
}

fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::SlashReason),
}
}
Loading

0 comments on commit 8b127b1

Please sign in to comment.