Metadata V15: Expose types for the overarching Call, Event, Error enums (#14143)

* frame-metadata: Point to unreleased branch

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Generalize outer enum generation for events and errors

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Remove individual generation of outer enum events

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* primitives/traits: Add marker trait for outer runtime enums

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Derive Clone, PartialEq, Eq for RuntimeEvents only

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/pallet: Include `#[pallet::error]` enum into pallet parts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* metadata-ir: Include call, event, error types

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/metadata: Include outer enum types in V15 metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/tests: Ensure `RuntimeError` includes `#[pallet::error]` parts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/support: Document the reserved name for `RuntimeError`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Use self-generated `RuntimeEvent` for `GetRuntimeOuterEnumTypes`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/ui: Fix UI tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/support: Remove unused system path

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/ui: Unexpected field and reintroduce frame_system::Config for RuntimeCall

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/support: Remove `GetRuntimeOuterEnumTypes` marker trait

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/support: Remove `;` from macro

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update frame-metadata to point to unreleased branch

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Rename error_enum_ty to module_error_enum_ty

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update module_error_ty documentation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Implement from_dispatch_error

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/support: Adjust test to ModuleErrorType

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Fix clippy

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Improve documentation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/tests: Check `from_dispatch_error` impl

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update frame-metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Remove the module_error_ty

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Apply fmt

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert unneeded parts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert "Revert unneeded parts"

This reverts commit b94bbd16078a025775a48da1095edec1705e6a4d.

Revert "Apply fmt"

This reverts commit 9b1c3e7b4ef27d32e10b35054a99916067e0397b.

Revert "Remove the module_error_ty"

This reverts commit 98de5b24653f9f9ec6ee842b749401b18a01758a.

* Update frame-metadata to origin/master

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Add outerEnums to the metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Add tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Keep backwards compatibility for explicit pallet parts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Rename tt_error_part to be more generic

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Increase recursion_limit to 1k

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Rename `fully_expanded` to `expanded`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Improve documentation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Adjust UI tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update UI tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update undefined_validate_unsigned_part.stderr UI test

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Adjust yet again

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Optimise macro expansions

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Use latest frame-metadata and rename `moduleErrorType` to `RuntimeError`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Fix comment

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Apply fmt

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update frame/support/procedural/src/construct_runtime/parse.rs

Co-authored-by: Bastian Köcher <git@kchr.de>

* Update frame/support/procedural/src/construct_runtime/parse.rs

Co-authored-by: Bastian Köcher <git@kchr.de>

* Update frame-metadata PR

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Remove `expanded` from error messages and fix typo

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Move docs to the function

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* ui: Use the intermed syntax for pallet parts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update frame-metadata with latest release

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Address feedback for `from_dispatch_error`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
Alexandru Vasile
2023-06-28 12:44:05 +03:00
committed by GitHub
parent 4249643df2
commit 73a368c2e4
33 changed files with 1143 additions and 337 deletions
@@ -0,0 +1,19 @@
// 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.
///! Common functionality between tests.
pub mod outer_enums;
@@ -0,0 +1,146 @@
// 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.
// Create 3 pallets for testing the outer error enum construction:
//
// - `pallet`: declares an error with `#[pallet::error]`
// - `pallet2`: declares an error with `#[pallet::error]`
// - `pallet3`: does not declare an error.
#[frame_support::pallet(dev_mode)]
pub mod pallet {
use frame_support::pallet_prelude::*;
#[pallet::config]
pub trait Config<I: 'static = ()>: frame_system::Config {
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
#[pallet::event]
pub enum Event<T: Config<I>, I: 'static = ()> {
/// Something
Something(u32),
}
#[pallet::pallet]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
phantom: PhantomData<(T, I)>,
}
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
GenesisConfig { phantom: Default::default() }
}
}
#[pallet::genesis_build]
impl<T: Config<I>, I: 'static> GenesisBuild<T, I> for GenesisConfig<T, I> {
fn build(&self) {}
}
#[pallet::error]
#[derive(PartialEq, Eq)]
pub enum Error<T, I = ()> {
/// doc comment put into metadata
InsufficientProposersBalance,
NonExistentStorageValue,
}
}
#[frame_support::pallet]
pub mod pallet2 {
use frame_support::pallet_prelude::*;
#[pallet::config]
pub trait Config<I: 'static = ()>: frame_system::Config {
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
#[pallet::event]
pub enum Event<T: Config<I>, I: 'static = ()> {
/// Something
Something(u32),
}
#[pallet::pallet]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
phantom: PhantomData<(T, I)>,
}
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
GenesisConfig { phantom: Default::default() }
}
}
#[pallet::genesis_build]
impl<T: Config<I>, I: 'static> GenesisBuild<T, I> for GenesisConfig<T, I> {
fn build(&self) {}
}
#[pallet::error]
#[derive(PartialEq, Eq)]
pub enum Error<T, I = ()> {
/// doc comment put into metadata
OtherInsufficientProposersBalance,
OtherNonExistentStorageValue,
}
}
#[frame_support::pallet]
pub mod pallet3 {
use frame_support::pallet_prelude::*;
#[pallet::config]
pub trait Config<I: 'static = ()>: frame_system::Config {
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
#[pallet::event]
pub enum Event<T: Config<I>, I: 'static = ()> {
/// Something
Something(u32),
}
#[pallet::pallet]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
phantom: PhantomData<(T, I)>,
}
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
GenesisConfig { phantom: Default::default() }
}
}
#[pallet::genesis_build]
impl<T: Config<I>, I: 'static> GenesisBuild<T, I> for GenesisConfig<T, I> {
fn build(&self) {}
}
}
@@ -1,4 +1,4 @@
error: `Call` is not allowed to have generics. Only the following pallets are allowed to have generics: `Event`, `Origin`, `Config`.
error: `Call` is not allowed to have generics. Only the following pallets are allowed to have generics: `Event`, `Error`, `Origin`, `Config`.
--> $DIR/generics_in_invalid_module.rs:10:36
|
10 | Balance: balances::<Instance1>::{Call<T>, Origin<T>},
@@ -1,4 +1,4 @@
error: expected one of: `Pallet`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned`, `FreezeReason`, `HoldReason`, `LockId`, `SlashReason`
error: expected one of: `Pallet`, `Call`, `Storage`, `Event`, `Error`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned`, `FreezeReason`, `HoldReason`, `LockId`, `SlashReason`
--> $DIR/invalid_module_details_keyword.rs:9:20
|
9 | system: System::{enum},
@@ -7,7 +7,7 @@ construct_runtime! {
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{Pallet},
Balance: balances::{Error},
Balance: balances::{Unexpected},
}
}
@@ -1,5 +1,5 @@
error: expected one of: `Pallet`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned`, `FreezeReason`, `HoldReason`, `LockId`, `SlashReason`
error: expected one of: `Pallet`, `Call`, `Storage`, `Event`, `Error`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned`, `FreezeReason`, `HoldReason`, `LockId`, `SlashReason`
--> $DIR/invalid_module_entry.rs:10:23
|
10 | Balance: balances::{Error},
| ^^^^^
10 | Balance: balances::{Unexpected},
| ^^^^^^^^^^
@@ -6,8 +6,8 @@ construct_runtime! {
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{Pallet},
Balance: balances::<Instance1>::{Event},
System: system expanded::{}::{Pallet},
Balance: balances::<Instance1> expanded::{}::{Event},
}
}
@@ -1,5 +1,5 @@
error: Instantiable pallet with no generic `Event` cannot be constructed: pallet `Balance` must have generic `Event`
--> $DIR/missing_event_generic_on_module_with_instance.rs:10:3
|
10 | Balance: balances::<Instance1>::{Event},
10 | Balance: balances::<Instance1> expanded::{}::{Event},
| ^^^^^^^
@@ -6,8 +6,8 @@ construct_runtime! {
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{Pallet},
Balance: balances::<Instance1>::{Origin},
System: system expanded::{}::{Pallet},
Balance: balances::<Instance1> expanded::{}::{Origin},
}
}
@@ -1,5 +1,5 @@
error: Instantiable pallet with no generic `Origin` cannot be constructed: pallet `Balance` must have generic `Origin`
--> $DIR/missing_origin_generic_on_module_with_instance.rs:10:3
|
10 | Balance: balances::<Instance1>::{Origin},
10 | Balance: balances::<Instance1> expanded::{}::{Origin},
| ^^^^^^^
@@ -52,8 +52,8 @@ construct_runtime! {
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet::{Pallet, Event},
System: frame_system expanded::{}::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet expanded::{}::{Pallet, Event},
}
}
@@ -52,8 +52,8 @@ construct_runtime! {
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet::{Pallet, Config},
System: frame_system expanded::{}::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet expanded::{}::{Pallet, Config},
}
}
@@ -52,8 +52,8 @@ construct_runtime! {
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet::{Pallet, Inherent},
System: frame_system expanded::{}::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet expanded::{}::{Pallet, Inherent},
}
}
@@ -52,8 +52,8 @@ construct_runtime! {
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet::{Pallet, Origin},
System: frame_system expanded::{}::{Pallet, Call, Storage, Config, Event<T>},
Pallet: pallet expanded::{}::{Pallet, Origin},
}
}
@@ -1,6 +1,6 @@
use frame_support::construct_runtime;
use sp_runtime::{generic, traits::BlakeTwo256};
use sp_core::sr25519;
use sp_runtime::{generic, traits::BlakeTwo256};
#[frame_support::pallet]
mod pallet {
@@ -28,50 +28,54 @@ error[E0599]: no variant or associated item named `Pallet` found for enum `Runti
| || -^^^^^^ variant or associated item not found in `RuntimeCall`
| ||________|
| |
57 | | }
58 | | }
| |__- variant or associated item `Pallet` not found for this enum
... |
error[E0599]: no function or associated item named `pre_dispatch` found for struct `pallet::Pallet` in the current scope
--> tests/construct_runtime_ui/undefined_validate_unsigned_part.rs:49:1
|
11 | pub struct Pallet<T>(_);
| -------------------- function or associated item `pre_dispatch` not found for this struct
11 | pub struct Pallet<T>(_);
| -------------------- function or associated item `pre_dispatch` not found for this struct
...
49 | construct_runtime! {
| _^
50 | | pub struct Runtime where
51 | | Block = Block,
52 | | NodeBlock = Block,
49 | construct_runtime! {
| __^
| | _|
| ||
50 | || pub struct Runtime where
51 | || Block = Block,
52 | || NodeBlock = Block,
... ||
57 | || }
58 | || }
| ||_- in this macro invocation
... |
57 | | }
58 | | }
| |_^ function or associated item not found in `Pallet<Runtime>`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `pre_dispatch`, perhaps you need to implement one of them:
candidate #1: `SignedExtension`
candidate #2: `ValidateUnsigned`
= note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0599]: no function or associated item named `validate_unsigned` found for struct `pallet::Pallet` in the current scope
--> tests/construct_runtime_ui/undefined_validate_unsigned_part.rs:49:1
|
11 | pub struct Pallet<T>(_);
| -------------------- function or associated item `validate_unsigned` not found for this struct
11 | pub struct Pallet<T>(_);
| -------------------- function or associated item `validate_unsigned` not found for this struct
...
49 | construct_runtime! {
| _^
50 | | pub struct Runtime where
51 | | Block = Block,
52 | | NodeBlock = Block,
49 | construct_runtime! {
| __^
| | _|
| ||
50 | || pub struct Runtime where
51 | || Block = Block,
52 | || NodeBlock = Block,
... ||
57 | || }
58 | || }
| ||_- in this macro invocation
... |
57 | | }
58 | | }
| |_^ function or associated item not found in `Pallet<Runtime>`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `validate_unsigned`, perhaps you need to implement one of them:
candidate #1: `SignedExtension`
candidate #2: `ValidateUnsigned`
= note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `frame_support::construct_runtime` which comes from the expansion of the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -419,6 +419,39 @@ fn error_expand() {
);
}
#[test]
fn module_error_outer_enum_expand() {
// assert that all variants of the Example pallet are included into the
// RuntimeError definition.
match RuntimeError::Example(pallet::Error::InsufficientProposersBalance) {
RuntimeError::Example(example) => match example {
pallet::Error::InsufficientProposersBalance => (),
pallet::Error::NonExistentStorageValue => (),
// Extra pattern added by `construct_runtime`.
pallet::Error::__Ignore(_, _) => (),
},
_ => (),
};
}
#[test]
fn module_error_from_dispatch_error() {
let dispatch_err = DispatchError::Module(ModuleError {
index: 1,
error: [0; 4],
message: Some("InsufficientProposersBalance"),
});
let err = RuntimeError::from_dispatch_error(dispatch_err).unwrap();
match err {
RuntimeError::Example(pallet::Error::InsufficientProposersBalance) => (),
_ => panic!("Module error constructed incorrectly"),
};
// Only `ModuleError` is converted.
assert!(RuntimeError::from_dispatch_error(DispatchError::BadOrigin).is_none());
}
#[test]
fn instance_expand() {
// assert same type
@@ -0,0 +1,140 @@
// 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 frame_support::traits::ConstU32;
mod common;
use common::outer_enums::{pallet, pallet2};
pub type Header = sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>;
pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<u32, RuntimeCall, (), ()>;
impl frame_system::Config for Runtime {
type BaseCallFilter = frame_support::traits::Everything;
type RuntimeOrigin = RuntimeOrigin;
type Index = u64;
type BlockNumber = u32;
type RuntimeCall = RuntimeCall;
type Hash = sp_runtime::testing::H256;
type Hashing = sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
type Header = Header;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU32<250>;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
impl common::outer_enums::pallet::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet::Config<common::outer_enums::pallet::Instance1> for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet2::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet2::Config<common::outer_enums::pallet::Instance1> for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet3::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet3::Config<common::outer_enums::pallet::Instance1> for Runtime {
type RuntimeEvent = RuntimeEvent;
}
frame_support::construct_runtime!(
pub struct Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
// Exclude part `Storage` in order not to check its metadata in tests.
System: frame_system::{Pallet, Config, Call, Event<T> },
// This pallet exposes the Error type explicitly.
Example: common::outer_enums::pallet::{Pallet, Config<T>, Event<T>, Error<T>},
Instance1Example: common::outer_enums::pallet::<Instance1>::{ Pallet, Config<T>, Event<T> },
// This pallet does not mention the Error type, but it must be propagated (similarly to the polkadot/kusama).
Example2: common::outer_enums::pallet2::{Pallet, Config<T>, Event<T> },
Instance1Example2: common::outer_enums::pallet2::<Instance1>::{Pallet, Config<T>, Event<T>},
// This pallet does not declare any errors.
Example3: common::outer_enums::pallet3::{Pallet, Config<T>, Event<T>},
Instance1Example3: common::outer_enums::pallet3::<Instance1>::{Pallet, Config<T>, Event<T>},
}
);
#[test]
fn module_error_outer_enum_expand_explicit() {
// The Runtime has *all* parts explicitly defined.
// Check that all error types are propagated
match RuntimeError::Example(pallet::Error::InsufficientProposersBalance) {
// Error passed implicitely to the pallet system.
RuntimeError::System(system) => match system {
frame_system::Error::InvalidSpecName => (),
frame_system::Error::SpecVersionNeedsToIncrease => (),
frame_system::Error::FailedToExtractRuntimeVersion => (),
frame_system::Error::NonDefaultComposite => (),
frame_system::Error::NonZeroRefCount => (),
frame_system::Error::CallFiltered => (),
frame_system::Error::__Ignore(_, _) => (),
},
// Error declared explicitly.
RuntimeError::Example(example) => match example {
pallet::Error::InsufficientProposersBalance => (),
pallet::Error::NonExistentStorageValue => (),
pallet::Error::__Ignore(_, _) => (),
},
// Error declared explicitly.
RuntimeError::Instance1Example(example) => match example {
pallet::Error::InsufficientProposersBalance => (),
pallet::Error::NonExistentStorageValue => (),
pallet::Error::__Ignore(_, _) => (),
},
// Error must propagate even if not defined explicitly as pallet part.
RuntimeError::Example2(example) => match example {
pallet2::Error::OtherInsufficientProposersBalance => (),
pallet2::Error::OtherNonExistentStorageValue => (),
pallet2::Error::__Ignore(_, _) => (),
},
// Error must propagate even if not defined explicitly as pallet part.
RuntimeError::Instance1Example2(example) => match example {
pallet2::Error::OtherInsufficientProposersBalance => (),
pallet2::Error::OtherNonExistentStorageValue => (),
pallet2::Error::__Ignore(_, _) => (),
},
};
}
@@ -0,0 +1,140 @@
// 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 frame_support::traits::ConstU32;
mod common;
use common::outer_enums::{pallet, pallet2};
pub type Header = sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>;
pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<u32, RuntimeCall, (), ()>;
impl frame_system::Config for Runtime {
type BaseCallFilter = frame_support::traits::Everything;
type RuntimeOrigin = RuntimeOrigin;
type Index = u64;
type BlockNumber = u32;
type RuntimeCall = RuntimeCall;
type Hash = sp_runtime::testing::H256;
type Hashing = sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
type Header = Header;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU32<250>;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
impl common::outer_enums::pallet::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet::Config<common::outer_enums::pallet::Instance1> for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet2::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet2::Config<common::outer_enums::pallet::Instance1> for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet3::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
impl common::outer_enums::pallet3::Config<common::outer_enums::pallet::Instance1> for Runtime {
type RuntimeEvent = RuntimeEvent;
}
frame_support::construct_runtime!(
pub struct Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
// Exclude part `Storage` in order not to check its metadata in tests.
System: frame_system exclude_parts { Storage },
// Pallet exposes `Error` implicitely.
Example: common::outer_enums::pallet,
Instance1Example: common::outer_enums::pallet::<Instance1>,
// Pallet exposes `Error` implicitely.
Example2: common::outer_enums::pallet2,
Instance1Example2: common::outer_enums::pallet2::<Instance1>,
// Pallet does not implement error.
Example3: common::outer_enums::pallet3,
Instance1Example3: common::outer_enums::pallet3::<Instance1>,
}
);
#[test]
fn module_error_outer_enum_expand_implicit() {
// The Runtime has *all* parts implicitly defined.
// Check that all error types are propagated
match RuntimeError::Example(pallet::Error::InsufficientProposersBalance) {
// Error passed implicitely to the pallet system.
RuntimeError::System(system) => match system {
frame_system::Error::InvalidSpecName => (),
frame_system::Error::SpecVersionNeedsToIncrease => (),
frame_system::Error::FailedToExtractRuntimeVersion => (),
frame_system::Error::NonDefaultComposite => (),
frame_system::Error::NonZeroRefCount => (),
frame_system::Error::CallFiltered => (),
frame_system::Error::__Ignore(_, _) => (),
},
// Error declared explicitly.
RuntimeError::Example(example) => match example {
pallet::Error::InsufficientProposersBalance => (),
pallet::Error::NonExistentStorageValue => (),
pallet::Error::__Ignore(_, _) => (),
},
// Error declared explicitly.
RuntimeError::Instance1Example(example) => match example {
pallet::Error::InsufficientProposersBalance => (),
pallet::Error::NonExistentStorageValue => (),
pallet::Error::__Ignore(_, _) => (),
},
// Error must propagate even if not defined explicitly as pallet part.
RuntimeError::Example2(example) => match example {
pallet2::Error::OtherInsufficientProposersBalance => (),
pallet2::Error::OtherNonExistentStorageValue => (),
pallet2::Error::__Ignore(_, _) => (),
},
// Error must propagate even if not defined explicitly as pallet part.
RuntimeError::Instance1Example2(example) => match example {
pallet2::Error::OtherInsufficientProposersBalance => (),
pallet2::Error::OtherNonExistentStorageValue => (),
pallet2::Error::__Ignore(_, _) => (),
},
};
}