Allow pallet's info to be enumerated (#10053)

* Allow pallet's info to be enumerated

* Fixes

* Formatting

* Flat tuple for getting all pallet instances

* Renaming and fixing reversedness

* Formatting

* Fixes

* Back to nesting

* Back to nestingx

* Revert executive lib

* Reversions

* Reversions

* Fixes

* Fixes

* Formatting

* Fixes

* Spelling

* Comments
This commit is contained in:
Gavin Wood
2021-10-21 10:29:10 +02:00
committed by GitHub
parent 1660bc8cf2
commit 1dc753eb08
9 changed files with 187 additions and 7 deletions
@@ -19,6 +19,7 @@
use codec::{Decode, Encode};
use sp_runtime::RuntimeDebug;
use sp_std::prelude::*;
/// Provides information about the pallet itself and its setup in the runtime.
///
@@ -35,6 +36,19 @@ pub trait PalletInfo {
fn crate_version<P: 'static>() -> Option<CrateVersion>;
}
/// Information regarding an instance of a pallet.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)]
pub struct PalletInfoData {
/// Index of the pallet as configured in the runtime.
pub index: usize,
/// Name of the pallet as configured in the runtime.
pub name: &'static str,
/// Name of the Rust module containing the pallet.
pub module_name: &'static str,
/// Version of the crate containing the pallet.
pub crate_version: CrateVersion,
}
/// Provides information about the pallet itself and its setup in the runtime.
///
/// Declare some information and access the information provided by [`PalletInfo`] for a specific
@@ -50,6 +64,49 @@ pub trait PalletInfoAccess {
fn crate_version() -> CrateVersion;
}
/// Provide information about a bunch of pallets.
pub trait PalletsInfoAccess {
/// The number of pallets' information that this type represents.
///
/// You probably don't want this function but `infos()` instead.
fn count() -> usize {
0
}
/// Extend the given vector by all of the pallets' information that this type represents.
///
/// You probably don't want this function but `infos()` instead.
fn accumulate(_accumulator: &mut Vec<PalletInfoData>) {}
/// All of the pallets' information that this type represents.
fn infos() -> Vec<PalletInfoData> {
let mut result = Vec::with_capacity(Self::count());
Self::accumulate(&mut result);
result
}
}
impl PalletsInfoAccess for () {}
impl<T: PalletsInfoAccess> PalletsInfoAccess for (T,) {
fn count() -> usize {
T::count()
}
fn accumulate(acc: &mut Vec<PalletInfoData>) {
T::accumulate(acc)
}
}
impl<T1: PalletsInfoAccess, T2: PalletsInfoAccess> PalletsInfoAccess for (T1, T2) {
fn count() -> usize {
T1::count() + T2::count()
}
fn accumulate(acc: &mut Vec<PalletInfoData>) {
// The AllPallets type tuplises the pallets in reverse order, so we unreverse them here.
T2::accumulate(acc);
T1::accumulate(acc);
}
}
/// The function and pallet name of the Call.
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug)]
pub struct CallMetadata {
@@ -206,6 +263,37 @@ pub trait GetStorageVersion {
mod tests {
use super::*;
struct Pallet1;
impl PalletInfoAccess for Pallet1 {
fn index() -> usize {
1
}
fn name() -> &'static str {
"Pallet1"
}
fn module_name() -> &'static str {
"pallet1"
}
fn crate_version() -> CrateVersion {
CrateVersion::new(1, 0, 0)
}
}
struct Pallet2;
impl PalletInfoAccess for Pallet2 {
fn index() -> usize {
2
}
fn name() -> &'static str {
"Pallet2"
}
fn module_name() -> &'static str {
"pallet2"
}
fn crate_version() -> CrateVersion {
CrateVersion::new(1, 0, 0)
}
}
#[test]
fn check_storage_version_ordering() {
let version = StorageVersion::new(1);