mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
Allow pallet in construct_runtime to have fixed index (#6969)
* implement index for pallet + some tests * add test and doc * remove deprecated and document behavior * update internal doc * Apply suggestions from code review Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * address review * use index for all module, break construct_runtime * fix line length * implement migration helper funciton in scheduler * fix start at index 0 * Update frame/scheduler/src/lib.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/support/procedural/src/lib.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * bump frame-metadata crate * factorize * avoid some unwrap and remove nightly join * Update frame/support/src/event.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * fix test * add test and improve error message * factorize test * keep iterator, and use slice instead of vec * refactor to avoid to have expects * small refactor * Test something * Make sure we update the `Cargo.lock` * Apply suggestions from code review Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * return 2 error * Apply suggestions from code review Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update frame/scheduler/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * fix typo * Revert "fix typo" This reverts commit f2de8f2db34e8ac72bc9c34437c60dca3fa4ac22. * Revert "Update frame/scheduler/src/lib.rs" This reverts commit 6feb4605c6f784b64591e229de7a6fec6dbffb4b. Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
86594727d9
commit
98951b33a9
Generated
+2
-1
@@ -1567,7 +1567,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "frame-metadata"
|
||||
version = "11.0.0-rc6"
|
||||
version = "12.0.0-rc6"
|
||||
dependencies = [
|
||||
"parity-scale-codec",
|
||||
"serde",
|
||||
@@ -1636,6 +1636,7 @@ dependencies = [
|
||||
name = "frame-support-test"
|
||||
version = "2.0.0-rc6"
|
||||
dependencies = [
|
||||
"frame-metadata",
|
||||
"frame-support",
|
||||
"parity-scale-codec",
|
||||
"pretty_assertions",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "frame-metadata"
|
||||
version = "11.0.0-rc6"
|
||||
version = "12.0.0-rc6"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
|
||||
@@ -362,8 +362,10 @@ pub enum RuntimeMetadata {
|
||||
V9(RuntimeMetadataDeprecated),
|
||||
/// Version 10 for runtime metadata. No longer used.
|
||||
V10(RuntimeMetadataDeprecated),
|
||||
/// Version 11 for runtime metadata.
|
||||
V11(RuntimeMetadataV11),
|
||||
/// Version 11 for runtime metadata. No longer used.
|
||||
V11(RuntimeMetadataDeprecated),
|
||||
/// Version 12 for runtime metadata.
|
||||
V12(RuntimeMetadataV12),
|
||||
}
|
||||
|
||||
/// Enum that should fail.
|
||||
@@ -387,7 +389,7 @@ impl Decode for RuntimeMetadataDeprecated {
|
||||
/// The metadata of a runtime.
|
||||
#[derive(Eq, Encode, PartialEq, RuntimeDebug)]
|
||||
#[cfg_attr(feature = "std", derive(Decode, Serialize))]
|
||||
pub struct RuntimeMetadataV11 {
|
||||
pub struct RuntimeMetadataV12 {
|
||||
/// Metadata of all the modules.
|
||||
pub modules: DecodeDifferentArray<ModuleMetadata>,
|
||||
/// Metadata of the extrinsic.
|
||||
@@ -395,7 +397,7 @@ pub struct RuntimeMetadataV11 {
|
||||
}
|
||||
|
||||
/// The latest version of the metadata.
|
||||
pub type RuntimeMetadataLastVersion = RuntimeMetadataV11;
|
||||
pub type RuntimeMetadataLastVersion = RuntimeMetadataV12;
|
||||
|
||||
/// All metadata about an runtime module.
|
||||
#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
|
||||
@@ -407,6 +409,9 @@ pub struct ModuleMetadata {
|
||||
pub event: ODFnA<EventMetadata>,
|
||||
pub constants: DFnA<ModuleConstantMetadata>,
|
||||
pub errors: DFnA<ErrorMetadata>,
|
||||
/// Define the index of the module, this index will be used for the encoding of module event,
|
||||
/// call and origin variants.
|
||||
pub index: u8,
|
||||
}
|
||||
|
||||
type ODFnA<T> = Option<DFnA<T>>;
|
||||
@@ -420,6 +425,6 @@ impl Into<sp_core::OpaqueMetadata> for RuntimeMetadataPrefixed {
|
||||
|
||||
impl Into<RuntimeMetadataPrefixed> for RuntimeMetadataLastVersion {
|
||||
fn into(self) -> RuntimeMetadataPrefixed {
|
||||
RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V11(self))
|
||||
RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V12(self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,6 +438,25 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper to migrate scheduler when the pallet origin type has changed.
|
||||
pub fn migrate_origin<OldOrigin: Into<T::PalletsOrigin> + codec::Decode>() {
|
||||
Agenda::<T>::translate::<
|
||||
Vec<Option<Scheduled<<T as Trait>::Call, T::BlockNumber, OldOrigin, T::AccountId>>>, _
|
||||
>(|_, agenda| Some(
|
||||
agenda
|
||||
.into_iter()
|
||||
.map(|schedule| schedule.map(|schedule| Scheduled {
|
||||
maybe_id: schedule.maybe_id,
|
||||
priority: schedule.priority,
|
||||
call: schedule.call,
|
||||
maybe_periodic: schedule.maybe_periodic,
|
||||
origin: schedule.origin.into(),
|
||||
_phantom: Default::default(),
|
||||
}))
|
||||
.collect::<Vec<_>>()
|
||||
));
|
||||
}
|
||||
|
||||
fn do_schedule(
|
||||
when: DispatchTime<T::BlockNumber>,
|
||||
maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
|
||||
@@ -632,6 +651,7 @@ mod tests {
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
};
|
||||
use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy};
|
||||
use substrate_test_utils::assert_eq_uvec;
|
||||
use crate as scheduler;
|
||||
|
||||
mod logger {
|
||||
@@ -1161,8 +1181,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn migration_to_v2_works() {
|
||||
use substrate_test_utils::assert_eq_uvec;
|
||||
|
||||
new_test_ext().execute_with(|| {
|
||||
for i in 0..3u64 {
|
||||
let k = i.twox_64_concat();
|
||||
@@ -1264,4 +1282,118 @@ mod tests {
|
||||
assert_eq!(StorageVersion::get(), Releases::V2);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_migrate_origin() {
|
||||
new_test_ext().execute_with(|| {
|
||||
for i in 0..3u64 {
|
||||
let k = i.twox_64_concat();
|
||||
let old: Vec<Option<Scheduled<_, _, u32, u64>>> = vec![
|
||||
Some(Scheduled {
|
||||
maybe_id: None,
|
||||
priority: i as u8 + 10,
|
||||
call: Call::Logger(logger::Call::log(96, 100)),
|
||||
origin: 3u32,
|
||||
maybe_periodic: None,
|
||||
_phantom: Default::default(),
|
||||
}),
|
||||
None,
|
||||
Some(Scheduled {
|
||||
maybe_id: Some(b"test".to_vec()),
|
||||
priority: 123,
|
||||
origin: 2u32,
|
||||
call: Call::Logger(logger::Call::log(69, 1000)),
|
||||
maybe_periodic: Some((456u64, 10)),
|
||||
_phantom: Default::default(),
|
||||
}),
|
||||
];
|
||||
frame_support::migration::put_storage_value(
|
||||
b"Scheduler",
|
||||
b"Agenda",
|
||||
&k,
|
||||
old,
|
||||
);
|
||||
}
|
||||
|
||||
impl Into<OriginCaller> for u32 {
|
||||
fn into(self) -> OriginCaller {
|
||||
match self {
|
||||
3u32 => system::RawOrigin::Root.into(),
|
||||
2u32 => system::RawOrigin::None.into(),
|
||||
_ => unreachable!("test make no use of it"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scheduler::migrate_origin::<u32>();
|
||||
|
||||
assert_eq_uvec!(Agenda::<Test>::iter().collect::<Vec<_>>(), vec![
|
||||
(
|
||||
0,
|
||||
vec![
|
||||
Some(ScheduledV2::<_, _, OriginCaller, u64> {
|
||||
maybe_id: None,
|
||||
priority: 10,
|
||||
call: Call::Logger(logger::Call::log(96, 100)),
|
||||
maybe_periodic: None,
|
||||
origin: system::RawOrigin::Root.into(),
|
||||
_phantom: PhantomData::<u64>::default(),
|
||||
}),
|
||||
None,
|
||||
Some(ScheduledV2 {
|
||||
maybe_id: Some(b"test".to_vec()),
|
||||
priority: 123,
|
||||
call: Call::Logger(logger::Call::log(69, 1000)),
|
||||
maybe_periodic: Some((456u64, 10)),
|
||||
origin: system::RawOrigin::None.into(),
|
||||
_phantom: PhantomData::<u64>::default(),
|
||||
}),
|
||||
]),
|
||||
(
|
||||
1,
|
||||
vec![
|
||||
Some(ScheduledV2 {
|
||||
maybe_id: None,
|
||||
priority: 11,
|
||||
call: Call::Logger(logger::Call::log(96, 100)),
|
||||
maybe_periodic: None,
|
||||
origin: system::RawOrigin::Root.into(),
|
||||
_phantom: PhantomData::<u64>::default(),
|
||||
}),
|
||||
None,
|
||||
Some(ScheduledV2 {
|
||||
maybe_id: Some(b"test".to_vec()),
|
||||
priority: 123,
|
||||
call: Call::Logger(logger::Call::log(69, 1000)),
|
||||
maybe_periodic: Some((456u64, 10)),
|
||||
origin: system::RawOrigin::None.into(),
|
||||
_phantom: PhantomData::<u64>::default(),
|
||||
}),
|
||||
]
|
||||
),
|
||||
(
|
||||
2,
|
||||
vec![
|
||||
Some(ScheduledV2 {
|
||||
maybe_id: None,
|
||||
priority: 12,
|
||||
call: Call::Logger(logger::Call::log(96, 100)),
|
||||
maybe_periodic: None,
|
||||
origin: system::RawOrigin::Root.into(),
|
||||
_phantom: PhantomData::<u64>::default(),
|
||||
}),
|
||||
None,
|
||||
Some(ScheduledV2 {
|
||||
maybe_id: Some(b"test".to_vec()),
|
||||
priority: 123,
|
||||
call: Call::Logger(logger::Call::log(69, 1000)),
|
||||
maybe_periodic: Some((456u64, 10)),
|
||||
origin: system::RawOrigin::None.into(),
|
||||
_phantom: PhantomData::<u64>::default(),
|
||||
}),
|
||||
]
|
||||
)
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
||||
log = "0.4"
|
||||
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] }
|
||||
frame-metadata = { version = "11.0.0-rc6", default-features = false, path = "../metadata" }
|
||||
frame-metadata = { version = "12.0.0-rc6", default-features = false, path = "../metadata" }
|
||||
sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" }
|
||||
sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" }
|
||||
sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" }
|
||||
|
||||
@@ -19,15 +19,86 @@ mod parse;
|
||||
|
||||
use frame_support_procedural_tools::syn_ext as ext;
|
||||
use frame_support_procedural_tools::{generate_crate_access, generate_hidden_includes};
|
||||
use parse::{ModuleDeclaration, RuntimeDefinition, WhereSection};
|
||||
use parse::{ModuleDeclaration, RuntimeDefinition, WhereSection, ModulePart};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro2::{TokenStream as TokenStream2};
|
||||
use quote::quote;
|
||||
use syn::{Ident, Result, TypePath};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// The fixed name of the system module.
|
||||
const SYSTEM_MODULE_NAME: &str = "System";
|
||||
|
||||
/// The complete definition of a module with the resulting fixed index.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Module {
|
||||
pub name: Ident,
|
||||
pub index: u8,
|
||||
pub module: Ident,
|
||||
pub instance: Option<Ident>,
|
||||
pub module_parts: Vec<ModulePart>,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
/// Get resolved module parts
|
||||
fn module_parts(&self) -> &[ModulePart] {
|
||||
&self.module_parts
|
||||
}
|
||||
|
||||
/// Find matching parts
|
||||
fn find_part(&self, name: &str) -> Option<&ModulePart> {
|
||||
self.module_parts.iter().find(|part| part.name() == name)
|
||||
}
|
||||
|
||||
/// Return whether module contains part
|
||||
fn exists_part(&self, name: &str) -> bool {
|
||||
self.find_part(name).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from the parsed module to their final information.
|
||||
/// Assign index to each modules using same rules as rust for fieldless enum.
|
||||
/// I.e. implicit are assigned number incrementedly from last explicit or 0.
|
||||
fn complete_modules(decl: impl Iterator<Item = ModuleDeclaration>) -> syn::Result<Vec<Module>> {
|
||||
let mut indices = HashMap::new();
|
||||
let mut last_index: Option<u8> = None;
|
||||
|
||||
decl
|
||||
.map(|module| {
|
||||
let final_index = match module.index {
|
||||
Some(i) => i,
|
||||
None => last_index.map_or(Some(0), |i| i.checked_add(1))
|
||||
.ok_or_else(|| {
|
||||
let msg = "Module index doesn't fit into u8, index is 256";
|
||||
syn::Error::new(module.name.span(), msg)
|
||||
})?,
|
||||
};
|
||||
|
||||
last_index = Some(final_index);
|
||||
|
||||
if let Some(used_module) = indices.insert(final_index, module.name.clone()) {
|
||||
let msg = format!(
|
||||
"Module indices are conflicting: Both modules {} and {} are at index {}",
|
||||
used_module,
|
||||
module.name,
|
||||
final_index,
|
||||
);
|
||||
let mut err = syn::Error::new(used_module.span(), &msg);
|
||||
err.combine(syn::Error::new(module.name.span(), msg));
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
Ok(Module {
|
||||
name: module.name,
|
||||
index: final_index,
|
||||
module: module.module,
|
||||
instance: module.instance,
|
||||
module_parts: module.module_parts,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn construct_runtime(input: TokenStream) -> TokenStream {
|
||||
let definition = syn::parse_macro_input!(input as RuntimeDefinition);
|
||||
construct_runtime_parsed(definition)
|
||||
@@ -52,19 +123,16 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream
|
||||
..
|
||||
} = definition;
|
||||
|
||||
let modules = modules.into_pairs().map(|v| v.into_value()).collect::<Vec<_>>();
|
||||
let modules = complete_modules(modules.into_iter())?;
|
||||
|
||||
let system_module = modules.iter()
|
||||
.find(|decl| decl.name == SYSTEM_MODULE_NAME)
|
||||
.ok_or_else(|| syn::Error::new(
|
||||
modules_token.span,
|
||||
"`System` module declaration is missing. \
|
||||
Please add this line: `System: frame_system::{Module, Call, Storage, Config, Event<T>},`",
|
||||
))?;
|
||||
|
||||
// Assert we have system module declared
|
||||
let system_module = match find_system_module(modules.iter()) {
|
||||
Some(sm) => sm,
|
||||
None => {
|
||||
return Err(syn::Error::new(
|
||||
modules_token.span,
|
||||
"`System` module declaration is missing. \
|
||||
Please add this line: `System: frame_system::{Module, Call, Storage, Config, Event<T>},`",
|
||||
))
|
||||
}
|
||||
};
|
||||
let hidden_crate_name = "construct_runtime";
|
||||
let scrate = generate_crate_access(&hidden_crate_name, "frame-support");
|
||||
let scrate_decl = generate_hidden_includes(&hidden_crate_name, "frame-support");
|
||||
@@ -79,7 +147,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream
|
||||
|
||||
let outer_origin = decl_outer_origin(
|
||||
&name,
|
||||
all_but_system_modules.clone(),
|
||||
all_but_system_modules,
|
||||
&system_module,
|
||||
&scrate,
|
||||
)?;
|
||||
@@ -136,7 +204,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream
|
||||
|
||||
fn decl_validate_unsigned<'a>(
|
||||
runtime: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
scrate: &'a TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let modules_tokens = module_declarations
|
||||
@@ -154,7 +222,7 @@ fn decl_validate_unsigned<'a>(
|
||||
fn decl_outer_inherent<'a>(
|
||||
block: &'a syn::TypePath,
|
||||
unchecked_extrinsic: &'a syn::TypePath,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
scrate: &'a TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let modules_tokens = module_declarations.filter_map(|module_declaration| {
|
||||
@@ -178,7 +246,7 @@ fn decl_outer_inherent<'a>(
|
||||
|
||||
fn decl_outer_config<'a>(
|
||||
runtime: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
scrate: &'a TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let modules_tokens = module_declarations
|
||||
@@ -216,7 +284,7 @@ fn decl_outer_config<'a>(
|
||||
|
||||
fn decl_runtime_metadata<'a>(
|
||||
runtime: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
scrate: &'a TokenStream2,
|
||||
extrinsic: &TypePath,
|
||||
) -> TokenStream2 {
|
||||
@@ -240,7 +308,12 @@ fn decl_runtime_metadata<'a>(
|
||||
.as_ref()
|
||||
.map(|name| quote!(<#name>))
|
||||
.into_iter();
|
||||
quote!(#module::Module #(#instance)* as #name with #(#filtered_names)* ,)
|
||||
|
||||
let index = module_declaration.index;
|
||||
|
||||
quote!(
|
||||
#module::Module #(#instance)* as #name { index #index } with #(#filtered_names)*,
|
||||
)
|
||||
});
|
||||
quote!(
|
||||
#scrate::impl_runtime_metadata!{
|
||||
@@ -252,7 +325,7 @@ fn decl_runtime_metadata<'a>(
|
||||
|
||||
fn decl_outer_dispatch<'a>(
|
||||
runtime: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
scrate: &'a TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let modules_tokens = module_declarations
|
||||
@@ -260,8 +333,10 @@ fn decl_outer_dispatch<'a>(
|
||||
.map(|module_declaration| {
|
||||
let module = &module_declaration.module;
|
||||
let name = &module_declaration.name;
|
||||
quote!(#module::#name)
|
||||
let index = module_declaration.index.to_string();
|
||||
quote!(#[codec(index = #index)] #module::#name)
|
||||
});
|
||||
|
||||
quote!(
|
||||
#scrate::impl_outer_dispatch! {
|
||||
pub enum Call for #runtime where origin: Origin {
|
||||
@@ -273,12 +348,12 @@ fn decl_outer_dispatch<'a>(
|
||||
|
||||
fn decl_outer_origin<'a>(
|
||||
runtime_name: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
system_name: &'a Ident,
|
||||
modules_except_system: impl Iterator<Item = &'a Module>,
|
||||
system_module: &'a Module,
|
||||
scrate: &'a TokenStream2,
|
||||
) -> syn::Result<TokenStream2> {
|
||||
let mut modules_tokens = TokenStream2::new();
|
||||
for module_declaration in module_declarations {
|
||||
for module_declaration in modules_except_system {
|
||||
match module_declaration.find_part("Origin") {
|
||||
Some(module_entry) => {
|
||||
let module = &module_declaration.module;
|
||||
@@ -292,16 +367,23 @@ fn decl_outer_origin<'a>(
|
||||
);
|
||||
return Err(syn::Error::new(module_declaration.name.span(), msg));
|
||||
}
|
||||
let tokens = quote!(#module #instance #generics ,);
|
||||
let index = module_declaration.index.to_string();
|
||||
let tokens = quote!(#[codec(index = #index)] #module #instance #generics,);
|
||||
modules_tokens.extend(tokens);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
let system_name = &system_module.module;
|
||||
let system_index = system_module.index.to_string();
|
||||
|
||||
Ok(quote!(
|
||||
#scrate::impl_outer_origin! {
|
||||
pub enum Origin for #runtime_name where system = #system_name {
|
||||
pub enum Origin for #runtime_name where
|
||||
system = #system_name,
|
||||
system_index = #system_index
|
||||
{
|
||||
#modules_tokens
|
||||
}
|
||||
}
|
||||
@@ -310,7 +392,7 @@ fn decl_outer_origin<'a>(
|
||||
|
||||
fn decl_outer_event<'a>(
|
||||
runtime_name: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
scrate: &'a TokenStream2,
|
||||
) -> syn::Result<TokenStream2> {
|
||||
let mut modules_tokens = TokenStream2::new();
|
||||
@@ -328,7 +410,9 @@ fn decl_outer_event<'a>(
|
||||
);
|
||||
return Err(syn::Error::new(module_declaration.name.span(), msg));
|
||||
}
|
||||
let tokens = quote!(#module #instance #generics ,);
|
||||
|
||||
let index = module_declaration.index.to_string();
|
||||
let tokens = quote!(#[codec(index = #index)] #module #instance #generics,);
|
||||
modules_tokens.extend(tokens);
|
||||
}
|
||||
None => {}
|
||||
@@ -346,7 +430,7 @@ fn decl_outer_event<'a>(
|
||||
|
||||
fn decl_all_modules<'a>(
|
||||
runtime: &'a Ident,
|
||||
module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
module_declarations: impl Iterator<Item = &'a Module>,
|
||||
) -> TokenStream2 {
|
||||
let mut types = TokenStream2::new();
|
||||
let mut names = Vec::new();
|
||||
@@ -379,13 +463,14 @@ fn decl_all_modules<'a>(
|
||||
}
|
||||
|
||||
fn decl_pallet_runtime_setup(
|
||||
module_declarations: &[ModuleDeclaration],
|
||||
module_declarations: &[Module],
|
||||
scrate: &TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let names = module_declarations.iter().map(|d| &d.name);
|
||||
let names2 = module_declarations.iter().map(|d| &d.name);
|
||||
let name_strings = module_declarations.iter().map(|d| d.name.to_string());
|
||||
let indices = 0..module_declarations.len();
|
||||
let indices = module_declarations.iter()
|
||||
.map(|module| module.index as usize);
|
||||
|
||||
quote!(
|
||||
/// Provides an implementation of `PalletInfo` to provide information
|
||||
@@ -418,14 +503,6 @@ fn decl_pallet_runtime_setup(
|
||||
)
|
||||
}
|
||||
|
||||
fn find_system_module<'a>(
|
||||
mut module_declarations: impl Iterator<Item = &'a ModuleDeclaration>,
|
||||
) -> Option<&'a Ident> {
|
||||
module_declarations
|
||||
.find(|decl| decl.name == SYSTEM_MODULE_NAME)
|
||||
.map(|decl| &decl.module)
|
||||
}
|
||||
|
||||
fn decl_integrity_test(scrate: &TokenStream2) -> TokenStream2 {
|
||||
quote!(
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -149,9 +149,11 @@ impl Parse for WhereDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleDeclaration {
|
||||
pub name: Ident,
|
||||
/// Optional fixed index (e.g. `MyPallet ... = 3,`)
|
||||
pub index: Option<u8>,
|
||||
pub module: Ident,
|
||||
pub instance: Option<Ident>,
|
||||
pub module_parts: Vec<ModulePart>,
|
||||
@@ -175,32 +177,27 @@ impl Parse for ModuleDeclaration {
|
||||
let _: Token![::] = input.parse()?;
|
||||
let module_parts = parse_module_parts(input)?;
|
||||
|
||||
let index = if input.peek(Token![=]) {
|
||||
input.parse::<Token![=]>()?;
|
||||
let index = input.parse::<syn::LitInt>()?;
|
||||
let index = index.base10_parse::<u8>()?;
|
||||
Some(index)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let parsed = Self {
|
||||
name,
|
||||
module,
|
||||
instance,
|
||||
module_parts,
|
||||
index,
|
||||
};
|
||||
|
||||
Ok(parsed)
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleDeclaration {
|
||||
/// Get resolved module parts
|
||||
pub fn module_parts(&self) -> &[ModulePart] {
|
||||
&self.module_parts
|
||||
}
|
||||
|
||||
pub fn find_part(&self, name: &str) -> Option<&ModulePart> {
|
||||
self.module_parts.iter().find(|part| part.name() == name)
|
||||
}
|
||||
|
||||
pub fn exists_part(&self, name: &str) -> bool {
|
||||
self.find_part(name).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse [`ModulePart`]'s from a braces enclosed list that is split by commas, e.g.
|
||||
///
|
||||
/// `{ Call, Event }`
|
||||
|
||||
@@ -252,13 +252,13 @@ pub fn decl_storage(input: TokenStream) -> TokenStream {
|
||||
/// NodeBlock = runtime::Block,
|
||||
/// UncheckedExtrinsic = UncheckedExtrinsic
|
||||
/// {
|
||||
/// System: system::{Module, Call, Event<T>, Config<T>},
|
||||
/// Test: test::{Module, Call},
|
||||
/// Test2: test_with_long_module::{Module},
|
||||
/// System: system::{Module, Call, Event<T>, Config<T>} = 0,
|
||||
/// Test: test::{Module, Call} = 1,
|
||||
/// Test2: test_with_long_module::{Module, Event<T>},
|
||||
///
|
||||
/// // Module with instances
|
||||
/// Test3_Instance1: test3::<Instance1>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>},
|
||||
/// Test3_DefaultInstance: test3::{Module, Call, Storage, Event<T>, Config<T>, Origin<T>},
|
||||
/// Test3_DefaultInstance: test3::{Module, Call, Storage, Event<T>, Config<T>, Origin<T>} = 4,
|
||||
/// }
|
||||
/// )
|
||||
/// ```
|
||||
@@ -279,6 +279,18 @@ pub fn decl_storage(input: TokenStream) -> TokenStream {
|
||||
/// - `Inherent` - If the module provides/can check inherents.
|
||||
/// - `ValidateUnsigned` - If the module validates unsigned extrinsics.
|
||||
///
|
||||
/// `= $n` is an optional part allowing to define at which index the module variants in
|
||||
/// `OriginCaller`, `Call` and `Event` are encoded, and to define the ModuleToIndex value.
|
||||
///
|
||||
/// if `= $n` is not given, then index is resolved same as fieldless enum in Rust
|
||||
/// (i.e. incrementedly from previous index):
|
||||
/// ```nocompile
|
||||
/// module1 .. = 2,
|
||||
/// module2 .., // Here module2 is given index 3
|
||||
/// module3 .. = 0,
|
||||
/// module4 .., // Here module4 is given index 1
|
||||
/// ```
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// The population of the genesis storage depends on the order of modules. So, if one of your
|
||||
|
||||
@@ -1911,7 +1911,7 @@ macro_rules! impl_outer_dispatch {
|
||||
$(#[$attr:meta])*
|
||||
pub enum $call_type:ident for $runtime:ident where origin: $origin:ty {
|
||||
$(
|
||||
$module:ident::$camelcase:ident,
|
||||
$( #[codec(index = $index:tt)] )? $module:ident::$camelcase:ident,
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
@@ -1924,6 +1924,7 @@ macro_rules! impl_outer_dispatch {
|
||||
)]
|
||||
pub enum $call_type {
|
||||
$(
|
||||
$( #[codec(index = $index)] )?
|
||||
$camelcase ( $crate::dispatch::CallableCallFor<$camelcase, $runtime> )
|
||||
,)*
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ macro_rules! impl_outer_event {
|
||||
$name;
|
||||
$runtime;
|
||||
Modules { $( $rest_events )* };
|
||||
;
|
||||
{};
|
||||
);
|
||||
};
|
||||
// Generic + Instance
|
||||
@@ -355,17 +355,17 @@ macro_rules! impl_outer_event {
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
Modules {
|
||||
$module:ident $instance:ident<T>,
|
||||
$( #[codec(index = $index:tt)] )? $module:ident $instance:ident<T>,
|
||||
$( $rest_event_generic_instance:tt )*
|
||||
};
|
||||
$( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*;
|
||||
{ $( $parsed:tt )* };
|
||||
) => {
|
||||
$crate::impl_outer_event!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$runtime;
|
||||
Modules { $( $rest_event_generic_instance )* };
|
||||
$( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event<$runtime>{ $instance },;
|
||||
{ $( $parsed )* $module::Event<$runtime>{ $instance } index { $( $index )? }, };
|
||||
);
|
||||
};
|
||||
// Instance
|
||||
@@ -374,17 +374,17 @@ macro_rules! impl_outer_event {
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
Modules {
|
||||
$module:ident $instance:ident,
|
||||
$( #[codec(index = $index:tt)] )? $module:ident $instance:ident,
|
||||
$( $rest_event_instance:tt )*
|
||||
};
|
||||
$( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*;
|
||||
{ $( $parsed:tt )* };
|
||||
) => {
|
||||
$crate::impl_outer_event!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$runtime;
|
||||
Modules { $( $rest_event_instance )* };
|
||||
$( $module_name::Event $( <$generic_param> )* $( { $generic_instance } )?, )* $module::Event { $instance },;
|
||||
{ $( $parsed )* $module::Event { $instance } index { $( $index )? }, };
|
||||
);
|
||||
};
|
||||
// Generic
|
||||
@@ -393,17 +393,17 @@ macro_rules! impl_outer_event {
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
Modules {
|
||||
$module:ident<T>,
|
||||
$( #[codec(index = $index:tt)] )? $module:ident<T>,
|
||||
$( $rest_event_generic:tt )*
|
||||
};
|
||||
$( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*;
|
||||
{ $( $parsed:tt )* };
|
||||
) => {
|
||||
$crate::impl_outer_event!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$runtime;
|
||||
Modules { $( $rest_event_generic )* };
|
||||
$( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event<$runtime>,;
|
||||
{ $( $parsed )* $module::Event<$runtime> index { $( $index )? }, };
|
||||
);
|
||||
};
|
||||
// No Generic and no Instance
|
||||
@@ -412,17 +412,17 @@ macro_rules! impl_outer_event {
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
Modules {
|
||||
$module:ident,
|
||||
$( #[codec(index = $index:tt)] )? $module:ident,
|
||||
$( $rest_event_no_generic_no_instance:tt )*
|
||||
};
|
||||
$( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*;
|
||||
{ $( $parsed:tt )* };
|
||||
) => {
|
||||
$crate::impl_outer_event!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$runtime;
|
||||
Modules { $( $rest_event_no_generic_no_instance )* };
|
||||
$( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event,;
|
||||
{ $( $parsed )* $module::Event index { $( $index )? }, };
|
||||
);
|
||||
};
|
||||
|
||||
@@ -432,7 +432,14 @@ macro_rules! impl_outer_event {
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
Modules {};
|
||||
$( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*;
|
||||
{
|
||||
$(
|
||||
$module_name:ident::Event
|
||||
$( <$generic_param:ident> )?
|
||||
$( { $generic_instance:ident } )?
|
||||
index { $( $index:tt )? },
|
||||
)*
|
||||
};
|
||||
) => {
|
||||
$crate::paste::item! {
|
||||
#[derive(
|
||||
@@ -445,6 +452,7 @@ macro_rules! impl_outer_event {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum $name {
|
||||
$(
|
||||
$( #[codec(index = $index)] )?
|
||||
[< $module_name $(_ $generic_instance )? >](
|
||||
$module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? >
|
||||
),
|
||||
@@ -697,7 +705,7 @@ mod tests {
|
||||
pub enum TestEventSystemRenamed for TestRuntime2 {
|
||||
system_renamed,
|
||||
event_module<T>,
|
||||
event_module2<T>,
|
||||
#[codec(index = "5")] event_module2<T>,
|
||||
event_module3,
|
||||
}
|
||||
}
|
||||
@@ -796,4 +804,22 @@ mod tests {
|
||||
fn outer_event_metadata() {
|
||||
assert_eq!(EXPECTED_METADATA, TestRuntime::outer_event_metadata());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_codec() {
|
||||
let runtime_1_event_module_2 = TestEvent::event_module2(
|
||||
event_module2::Event::<TestRuntime>::TestEvent(3)
|
||||
);
|
||||
assert_eq!(runtime_1_event_module_2.encode()[0], 2);
|
||||
|
||||
let runtime_2_event_module_2 = TestEventSystemRenamed::event_module2(
|
||||
event_module2::Event::<TestRuntime2>::TestEvent(3)
|
||||
);
|
||||
assert_eq!(runtime_2_event_module_2.encode()[0], 5);
|
||||
|
||||
let runtime_2_event_module_3 = TestEventSystemRenamed::event_module3(
|
||||
event_module3::Event::HiEvent
|
||||
);
|
||||
assert_eq!(runtime_2_event_module_3.encode()[0], 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ pub use frame_metadata::{
|
||||
/// struct Runtime;
|
||||
/// frame_support::impl_runtime_metadata! {
|
||||
/// for Runtime with modules where Extrinsic = UncheckedExtrinsic
|
||||
/// module0::Module as Module0 with,
|
||||
/// module1::Module as Module1 with,
|
||||
/// module2::Module as Module2 with Storage,
|
||||
/// module0::Module as Module0 { index 0 } with,
|
||||
/// module1::Module as Module1 { index 1 } with,
|
||||
/// module2::Module as Module2 { index 2 } with Storage,
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
@@ -91,13 +91,17 @@ macro_rules! __runtime_modules_to_metadata {
|
||||
(
|
||||
$runtime: ident;
|
||||
$( $metadata:expr ),*;
|
||||
$mod:ident::$module:ident $( < $instance:ident > )? as $name:ident $(with)+ $($kw:ident)*,
|
||||
$mod:ident::$module:ident $( < $instance:ident > )? as $name:ident
|
||||
{ index $index:tt }
|
||||
$(with)+ $($kw:ident)*
|
||||
,
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$crate::__runtime_modules_to_metadata!(
|
||||
$runtime;
|
||||
$( $metadata, )* $crate::metadata::ModuleMetadata {
|
||||
name: $crate::metadata::DecodeDifferent::Encode(stringify!($name)),
|
||||
index: $index,
|
||||
storage: $crate::__runtime_modules_to_metadata_calls_storage!(
|
||||
$mod, $module $( <$instance> )?, $runtime, $(with $kw)*
|
||||
),
|
||||
@@ -449,9 +453,9 @@ mod tests {
|
||||
|
||||
impl_runtime_metadata!(
|
||||
for TestRuntime with modules where Extrinsic = TestExtrinsic
|
||||
system::Module as System with Event,
|
||||
event_module::Module as Module with Event Call,
|
||||
event_module2::Module as Module2 with Event Storage Call,
|
||||
system::Module as System { index 0 } with Event,
|
||||
event_module::Module as Module { index 1 } with Event Call,
|
||||
event_module2::Module as Module2 { index 2 } with Event Storage Call,
|
||||
);
|
||||
|
||||
struct ConstantBlockNumberByteGetter;
|
||||
@@ -481,6 +485,7 @@ mod tests {
|
||||
modules: DecodeDifferent::Encode(&[
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("System"),
|
||||
index: 0,
|
||||
storage: None,
|
||||
calls: None,
|
||||
event: Some(DecodeDifferent::Encode(
|
||||
@@ -524,6 +529,7 @@ mod tests {
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module"),
|
||||
index: 1,
|
||||
storage: None,
|
||||
calls: Some(
|
||||
DecodeDifferent::Encode(FnEncode(|| &[
|
||||
@@ -559,6 +565,7 @@ mod tests {
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module2"),
|
||||
index: 2,
|
||||
storage: Some(DecodeDifferent::Encode(
|
||||
FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("TestStorage"),
|
||||
|
||||
@@ -41,7 +41,10 @@ macro_rules! impl_outer_origin {
|
||||
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
pub enum $name:ident for $runtime:ident where system = $system:ident {
|
||||
pub enum $name:ident for $runtime:ident where
|
||||
system = $system:ident
|
||||
$(, system_index = $system_index:tt)?
|
||||
{
|
||||
$( $rest_with_system:tt )*
|
||||
}
|
||||
) => {
|
||||
@@ -52,6 +55,7 @@ macro_rules! impl_outer_origin {
|
||||
[< $name Caller >];
|
||||
$runtime;
|
||||
$system;
|
||||
system_index { $( $system_index )? };
|
||||
Modules { $( $rest_with_system )* };
|
||||
);
|
||||
}
|
||||
@@ -64,8 +68,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
system_index { $( $system_index:tt )? };
|
||||
Modules {
|
||||
$module:ident $instance:ident <T>
|
||||
$( #[codec(index = $index:tt)] )? $module:ident $instance:ident <T>
|
||||
$(, $( $rest_module:tt )* )?
|
||||
};
|
||||
$( $parsed:tt )*
|
||||
@@ -76,8 +81,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
system_index { $( $system_index )? };
|
||||
Modules { $( $( $rest_module )* )? };
|
||||
$( $parsed )* $module <$runtime> { $instance },
|
||||
$( $parsed )* $module <$runtime> { $instance } index { $( $index )? },
|
||||
);
|
||||
};
|
||||
|
||||
@@ -88,8 +94,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
system_index { $( $system_index:tt )? };
|
||||
Modules {
|
||||
$module:ident $instance:ident
|
||||
$( #[codec(index = $index:tt )] )? $module:ident $instance:ident
|
||||
$(, $rest_module:tt )*
|
||||
};
|
||||
$( $parsed:tt )*
|
||||
@@ -100,8 +107,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
system_index { $( $system_index )? };
|
||||
Modules { $( $rest_module )* };
|
||||
$( $parsed )* $module { $instance },
|
||||
$( $parsed )* $module { $instance } index { $( $index )? },
|
||||
);
|
||||
};
|
||||
|
||||
@@ -112,8 +120,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
system_index { $( $system_index:tt )? };
|
||||
Modules {
|
||||
$module:ident <T>
|
||||
$( #[codec(index = $index:tt )] )? $module:ident <T>
|
||||
$(, $( $rest_module:tt )* )?
|
||||
};
|
||||
$( $parsed:tt )*
|
||||
@@ -124,8 +133,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
system_index { $( $system_index )? };
|
||||
Modules { $( $( $rest_module )* )? };
|
||||
$( $parsed )* $module <$runtime>,
|
||||
$( $parsed )* $module <$runtime> index { $( $index )? },
|
||||
);
|
||||
};
|
||||
|
||||
@@ -136,8 +146,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
system_index { $( $system_index:tt )? };
|
||||
Modules {
|
||||
$module:ident
|
||||
$( #[codec(index = $index:tt )] )? $module:ident
|
||||
$(, $( $rest_module:tt )* )?
|
||||
};
|
||||
$( $parsed:tt )*
|
||||
@@ -148,8 +159,9 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
system_index { $( $system_index )? };
|
||||
Modules { $( $( $rest_module )* )? };
|
||||
$( $parsed )* $module,
|
||||
$( $parsed )* $module index { $( $index )? },
|
||||
);
|
||||
};
|
||||
|
||||
@@ -160,8 +172,14 @@ macro_rules! impl_outer_origin {
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
system_index { $( $system_index:tt )? };
|
||||
Modules { };
|
||||
$( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)*
|
||||
$(
|
||||
$module:ident
|
||||
$( < $generic:ident > )?
|
||||
$( { $generic_instance:ident } )?
|
||||
index { $( $index:tt )? },
|
||||
)*
|
||||
) => {
|
||||
// WARNING: All instance must hold the filter `frame_system::Trait::BaseCallFilter`, except
|
||||
// when caller is system Root. One can use `OriginTrait::reset_filter` to do so.
|
||||
@@ -233,8 +251,10 @@ macro_rules! impl_outer_origin {
|
||||
$(#[$attr])*
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum $caller_name {
|
||||
$( #[codec(index = $system_index)] )?
|
||||
system($system::Origin<$runtime>),
|
||||
$(
|
||||
$( #[codec(index = $index)] )?
|
||||
[< $module $( _ $generic_instance )? >]
|
||||
($module::Origin < $( $generic, )? $( $module::$generic_instance )? > ),
|
||||
)*
|
||||
@@ -442,6 +462,13 @@ mod tests {
|
||||
pub enum OriginEmpty for TestRuntime where system = frame_system {}
|
||||
);
|
||||
|
||||
impl_outer_origin!(
|
||||
pub enum OriginIndices for TestRuntime where system = frame_system, system_index = "11" {
|
||||
origin_with_generic<T>,
|
||||
#[codec(index = "10")] origin_without_generic,
|
||||
}
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn test_default_filter() {
|
||||
assert_eq!(OriginWithSystem::root().filter_call(&0), true);
|
||||
@@ -472,4 +499,20 @@ mod tests {
|
||||
assert_eq!(origin.filter_call(&0), true);
|
||||
assert_eq!(origin.filter_call(&1), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_codec() {
|
||||
use codec::Encode;
|
||||
assert_eq!(OriginIndices::root().caller.encode()[0], 11);
|
||||
let without_generic_variant = OriginIndicesCaller::origin_without_generic(
|
||||
origin_without_generic::Origin
|
||||
);
|
||||
assert_eq!(without_generic_variant.encode()[0], 10);
|
||||
|
||||
assert_eq!(OriginWithoutSystem::root().caller.encode()[0], 0);
|
||||
let without_generic_variant = OriginWithoutSystemCaller::origin_without_generic(
|
||||
origin_without_generic::Origin
|
||||
);
|
||||
assert_eq!(without_generic_variant.encode()[0], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../pri
|
||||
trybuild = "1.0.33"
|
||||
pretty_assertions = "0.6.1"
|
||||
rustversion = "1.0.0"
|
||||
frame-metadata = { version = "12.0.0-rc6", default-features = false, path = "../../metadata" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -50,6 +50,17 @@ mod module1 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, codec::Encode, codec::Decode)]
|
||||
pub struct Origin<T, I: Instance = DefaultInstance>(pub core::marker::PhantomData::<(T, I)>);
|
||||
|
||||
frame_support::decl_event! {
|
||||
pub enum Event<T, I: Instance = DefaultInstance> where
|
||||
<T as system::Trait>::AccountId
|
||||
{
|
||||
A(AccountId),
|
||||
}
|
||||
}
|
||||
|
||||
frame_support::decl_error! {
|
||||
pub enum Error for Module<T: Trait<I>, I: Instance> {
|
||||
Something
|
||||
@@ -81,6 +92,15 @@ mod module2 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, codec::Encode, codec::Decode)]
|
||||
pub struct Origin;
|
||||
|
||||
frame_support::decl_event! {
|
||||
pub enum Event {
|
||||
A,
|
||||
}
|
||||
}
|
||||
|
||||
frame_support::decl_error! {
|
||||
pub enum Error for Module<T: Trait> {
|
||||
Something
|
||||
@@ -92,8 +112,7 @@ mod module2 {
|
||||
}
|
||||
}
|
||||
|
||||
impl module1::Trait<module1::Instance1> for Runtime {}
|
||||
impl module1::Trait<module1::Instance2> for Runtime {}
|
||||
impl<I> module1::Trait<I> for Runtime {}
|
||||
impl module2::Trait for Runtime {}
|
||||
|
||||
pub type Signature = sr25519::Signature;
|
||||
@@ -118,10 +137,17 @@ frame_support::construct_runtime!(
|
||||
NodeBlock = Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
System: system::{Module, Call, Event<T>},
|
||||
Module1_1: module1::<Instance1>::{Module, Call, Storage},
|
||||
Module2: module2::{Module, Call, Storage},
|
||||
Module1_2: module1::<Instance2>::{Module, Call, Storage},
|
||||
System: system::{Module, Call, Event<T>, Origin<T>} = 30,
|
||||
Module1_1: module1::<Instance1>::{Module, Call, Storage, Event<T>, Origin<T>},
|
||||
Module2: module2::{Module, Call, Storage, Event, Origin},
|
||||
Module1_2: module1::<Instance2>::{Module, Call, Storage, Event<T>, Origin<T>},
|
||||
Module1_3: module1::<Instance3>::{Module, Storage} = 6,
|
||||
Module1_4: module1::<Instance4>::{Module, Call} = 3,
|
||||
Module1_5: module1::<Instance5>::{Module, Event<T>},
|
||||
Module1_6: module1::<Instance6>::{Module, Call, Storage, Event<T>, Origin<T>} = 1,
|
||||
Module1_7: module1::<Instance7>::{Module, Call, Storage, Event<T>, Origin<T>},
|
||||
Module1_8: module1::<Instance8>::{Module, Call, Storage, Event<T>, Origin<T>} = 12,
|
||||
Module1_9: module1::<Instance9>::{Module, Call, Storage, Event<T>, Origin<T>},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -130,27 +156,47 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, Call, Signature, ()>;
|
||||
|
||||
#[test]
|
||||
fn check_module1_1_error_type() {
|
||||
fn check_modules_error_type() {
|
||||
assert_eq!(
|
||||
Module1_1::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 1, error: 0, message: Some("Something") }),
|
||||
Err(DispatchError::Module { index: 31, error: 0, message: Some("Something") }),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_module1_2_error_type() {
|
||||
assert_eq!(
|
||||
Module1_2::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 3, error: 0, message: Some("Something") }),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_module2_error_type() {
|
||||
assert_eq!(
|
||||
Module2::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 32, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_2::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 33, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_3::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 6, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_4::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 3, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_5::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 4, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_6::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 1, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_7::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 2, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_8::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 12, error: 0, message: Some("Something") }),
|
||||
);
|
||||
assert_eq!(
|
||||
Module1_9::fail(system::Origin::<Runtime>::Root.into()),
|
||||
Err(DispatchError::Module { index: 13, error: 0, message: Some("Something") }),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -159,14 +205,340 @@ fn integrity_test_works() {
|
||||
assert_eq!(INTEGRITY_TEST_EXEC.with(|i| *i.borrow()), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn origin_codec() {
|
||||
use codec::Encode;
|
||||
|
||||
let origin = OriginCaller::system(system::RawOrigin::None);
|
||||
assert_eq!(origin.encode()[0], 30);
|
||||
|
||||
let origin = OriginCaller::module1_Instance1(module1::Origin(Default::default()));
|
||||
assert_eq!(origin.encode()[0], 31);
|
||||
|
||||
let origin = OriginCaller::module2(module2::Origin);
|
||||
assert_eq!(origin.encode()[0], 32);
|
||||
|
||||
let origin = OriginCaller::module1_Instance2(module1::Origin(Default::default()));
|
||||
assert_eq!(origin.encode()[0], 33);
|
||||
|
||||
let origin = OriginCaller::module1_Instance6(module1::Origin(Default::default()));
|
||||
assert_eq!(origin.encode()[0], 1);
|
||||
|
||||
let origin = OriginCaller::module1_Instance7(module1::Origin(Default::default()));
|
||||
assert_eq!(origin.encode()[0], 2);
|
||||
|
||||
let origin = OriginCaller::module1_Instance8(module1::Origin(Default::default()));
|
||||
assert_eq!(origin.encode()[0], 12);
|
||||
|
||||
let origin = OriginCaller::module1_Instance9(module1::Origin(Default::default()));
|
||||
assert_eq!(origin.encode()[0], 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event_codec() {
|
||||
use codec::Encode;
|
||||
|
||||
let event = system::Event::<Runtime>::ExtrinsicSuccess;
|
||||
assert_eq!(Event::from(event).encode()[0], 30);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance1>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 31);
|
||||
|
||||
let event = module2::Event::A;
|
||||
assert_eq!(Event::from(event).encode()[0], 32);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance2>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 33);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance5>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 4);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance6>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 1);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance7>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 2);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance8>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 12);
|
||||
|
||||
let event = module1::Event::<Runtime, module1::Instance9>::A(Default::default());
|
||||
assert_eq!(Event::from(event).encode()[0], 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn call_codec() {
|
||||
use codec::Encode;
|
||||
assert_eq!(Call::System(system::Call::noop()).encode()[0], 30);
|
||||
assert_eq!(Call::Module1_1(module1::Call::fail()).encode()[0], 31);
|
||||
assert_eq!(Call::Module2(module2::Call::fail()).encode()[0], 32);
|
||||
assert_eq!(Call::Module1_2(module1::Call::fail()).encode()[0], 33);
|
||||
assert_eq!(Call::Module1_4(module1::Call::fail()).encode()[0], 3);
|
||||
assert_eq!(Call::Module1_6(module1::Call::fail()).encode()[0], 1);
|
||||
assert_eq!(Call::Module1_7(module1::Call::fail()).encode()[0], 2);
|
||||
assert_eq!(Call::Module1_8(module1::Call::fail()).encode()[0], 12);
|
||||
assert_eq!(Call::Module1_9(module1::Call::fail()).encode()[0], 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_metadata() {
|
||||
use frame_metadata::*;
|
||||
let expected_metadata: RuntimeMetadataLastVersion = RuntimeMetadataLastVersion {
|
||||
modules: DecodeDifferent::Encode(&[
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("System"),
|
||||
storage: None,
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("noop"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("ExtrinsicSuccess"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("ExtrinsicFailed"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("Ignore"),
|
||||
arguments: DecodeDifferent::Encode(&["BlockNumber"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 30,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_1"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance1Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[
|
||||
FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 31,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module2"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[
|
||||
FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 32,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_2"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance2Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 33,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_3"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance3Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: None,
|
||||
event: None,
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 6,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_4"),
|
||||
storage: None,
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: None,
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 3,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_5"),
|
||||
storage: None,
|
||||
calls: None,
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 4,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_6"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance6Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 1,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_7"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance7Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 2,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_8"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance8Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 12,
|
||||
},
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module1_9"),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("Instance9Module"),
|
||||
entries: DecodeDifferent::Encode(&[]),
|
||||
}))),
|
||||
calls: Some(DecodeDifferent::Encode(FnEncode(|| &[FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("fail"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
event: Some(DecodeDifferent::Encode(FnEncode(|| &[EventMetadata {
|
||||
name: DecodeDifferent::Encode("A"),
|
||||
arguments: DecodeDifferent::Encode(&["AccountId"]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}]))),
|
||||
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
|
||||
index: 13,
|
||||
},
|
||||
]),
|
||||
extrinsic: ExtrinsicMetadata {
|
||||
version: 4,
|
||||
signed_extensions: vec![DecodeDifferent::Encode("UnitSignedExtension")],
|
||||
},
|
||||
};
|
||||
pretty_assertions::assert_eq!(Runtime::metadata().1, RuntimeMetadata::V12(expected_metadata));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pallet_in_runtime_is_correct() {
|
||||
assert_eq!(PalletInfo::index::<System>().unwrap(), 0);
|
||||
assert_eq!(PalletInfo::index::<System>().unwrap(), 30);
|
||||
assert_eq!(PalletInfo::name::<System>().unwrap(), "System");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_2>().unwrap(), 3);
|
||||
assert_eq!(PalletInfo::index::<Module1_1>().unwrap(), 31);
|
||||
assert_eq!(PalletInfo::name::<Module1_1>().unwrap(), "Module1_1");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module2>().unwrap(), 32);
|
||||
assert_eq!(PalletInfo::name::<Module2>().unwrap(), "Module2");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_2>().unwrap(), 33);
|
||||
assert_eq!(PalletInfo::name::<Module1_2>().unwrap(), "Module1_2");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module2>().unwrap(), 2);
|
||||
assert_eq!(PalletInfo::name::<Module2>().unwrap(), "Module2");
|
||||
assert_eq!(PalletInfo::index::<Module1_3>().unwrap(), 6);
|
||||
assert_eq!(PalletInfo::name::<Module1_3>().unwrap(), "Module1_3");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_4>().unwrap(), 3);
|
||||
assert_eq!(PalletInfo::name::<Module1_4>().unwrap(), "Module1_4");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_5>().unwrap(), 4);
|
||||
assert_eq!(PalletInfo::name::<Module1_5>().unwrap(), "Module1_5");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_6>().unwrap(), 1);
|
||||
assert_eq!(PalletInfo::name::<Module1_6>().unwrap(), "Module1_6");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_7>().unwrap(), 2);
|
||||
assert_eq!(PalletInfo::name::<Module1_7>().unwrap(), "Module1_7");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_8>().unwrap(), 12);
|
||||
assert_eq!(PalletInfo::name::<Module1_8>().unwrap(), "Module1_8");
|
||||
|
||||
assert_eq!(PalletInfo::index::<Module1_9>().unwrap(), 13);
|
||||
assert_eq!(PalletInfo::name::<Module1_9>().unwrap(), "Module1_9");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
use frame_support::construct_runtime;
|
||||
|
||||
construct_runtime! {
|
||||
pub enum Runtime where
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
{
|
||||
System: system::{},
|
||||
Pallet1: pallet1::{} = 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,11 @@
|
||||
error: Module indices are conflicting: Both modules System and Pallet1 are at index 0
|
||||
--> $DIR/conflicting_index.rs:9:3
|
||||
|
|
||||
9 | System: system::{},
|
||||
| ^^^^^^
|
||||
|
||||
error: Module indices are conflicting: Both modules System and Pallet1 are at index 0
|
||||
--> $DIR/conflicting_index.rs:10:3
|
||||
|
|
||||
10 | Pallet1: pallet1::{} = 0,
|
||||
| ^^^^^^^
|
||||
@@ -0,0 +1,16 @@
|
||||
use frame_support::construct_runtime;
|
||||
|
||||
construct_runtime! {
|
||||
pub enum Runtime where
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
{
|
||||
System: system::{} = 5,
|
||||
Pallet1: pallet1::{} = 3,
|
||||
Pallet2: pallet2::{},
|
||||
Pallet3: pallet3::{},
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,11 @@
|
||||
error: Module indices are conflicting: Both modules System and Pallet3 are at index 5
|
||||
--> $DIR/conflicting_index_2.rs:9:3
|
||||
|
|
||||
9 | System: system::{} = 5,
|
||||
| ^^^^^^
|
||||
|
||||
error: Module indices are conflicting: Both modules System and Pallet3 are at index 5
|
||||
--> $DIR/conflicting_index_2.rs:12:3
|
||||
|
|
||||
12 | Pallet3: pallet3::{},
|
||||
| ^^^^^^^
|
||||
@@ -0,0 +1,14 @@
|
||||
use frame_support::construct_runtime;
|
||||
|
||||
construct_runtime! {
|
||||
pub enum Runtime where
|
||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
{
|
||||
System: system::{} = 255,
|
||||
Pallet256: pallet256::{},
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: Module index doesn't fit into u8, index is 256
|
||||
--> $DIR/more_than_256_modules.rs:10:3
|
||||
|
|
||||
10 | Pallet256: pallet256::{},
|
||||
| ^^^^^^^^^
|
||||
@@ -31,7 +31,10 @@ pub trait Trait: 'static + Eq + Clone {
|
||||
}
|
||||
|
||||
frame_support::decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin, system=self {}
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin, system=self {
|
||||
#[weight = 0]
|
||||
fn noop(origin) {}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
|
||||
Reference in New Issue
Block a user