mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 04:37:57 +00:00
Per-transaction weight for srml (#2799)
* debug checkpoint. * new * Worked. * Worked and weight propagated to executive. * Works with some tests. * Cleanup debug prints. * More cleanup. * Undo more logs. * Undo a few more. * Fix build. * Allow len to be used in weight calculation. * Remove noop function from dispath. * Cleanup. * Unify traits. * Update docs and nits. * line width * Update core/sr-primitives/src/weights.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update core/sr-primitives/src/weights.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update core/sr-primitives/src/weights.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update core/sr-primitives/src/weights.rs Co-Authored-By: Amar Singh <asinghchrony@protonmail.com> * Update srml/example/src/lib.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Final cleanup. * Fix build.
This commit is contained in:
@@ -23,6 +23,7 @@ pub use std::fmt;
|
||||
pub use crate::rstd::result;
|
||||
pub use crate::codec::{Codec, Decode, Encode, Input, Output, HasCompact, EncodeAsRef};
|
||||
pub use srml_metadata::{FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata};
|
||||
pub use sr_primitives::weights::{TransactionWeight, Weighable, Weight};
|
||||
|
||||
/// A type that cannot be instantiated.
|
||||
pub enum Never {}
|
||||
@@ -200,8 +201,7 @@ impl<T> Parameter for T where T: Codec + Clone + Eq {}
|
||||
/// [`OffchainWorker`](../sr_primitives/traits/trait.OffchainWorker.html) trait.
|
||||
#[macro_export]
|
||||
macro_rules! decl_module {
|
||||
// Macro transformations (to convert invocations with incomplete parameters to the canonical
|
||||
// form)
|
||||
// Entry point #1.
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -221,6 +221,7 @@ macro_rules! decl_module {
|
||||
$($t)*
|
||||
);
|
||||
};
|
||||
// Entry point #2.
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -241,6 +242,7 @@ macro_rules! decl_module {
|
||||
);
|
||||
};
|
||||
|
||||
// Normalization expansions. Fills the defaults.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -402,9 +404,13 @@ macro_rules! decl_module {
|
||||
$($rest)*
|
||||
);
|
||||
};
|
||||
// This puts the function statement into the [], decreasing `$rest` and moving toward finishing the parse.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
pub struct $mod_type:ident<
|
||||
$trait_instance:ident:
|
||||
$trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
|
||||
>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialize:tt )* }
|
||||
@@ -412,6 +418,7 @@ macro_rules! decl_module {
|
||||
{ $( $offchain:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
#[weight = $weight:expr]
|
||||
$fn_vis:vis fn $fn_name:ident(
|
||||
$origin:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)*
|
||||
) $( -> $result:ty )* { $( $impl:tt )* }
|
||||
@@ -419,7 +426,9 @@ macro_rules! decl_module {
|
||||
) => {
|
||||
$crate::decl_module!(@normalize
|
||||
$(#[$attr])*
|
||||
pub struct $mod_type<$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?>
|
||||
pub struct $mod_type<
|
||||
$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?
|
||||
>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $( $deposit_event )* }
|
||||
{ $( $on_initialize )* }
|
||||
@@ -428,6 +437,7 @@ macro_rules! decl_module {
|
||||
[
|
||||
$($t)*
|
||||
$(#[doc = $doc_attr])*
|
||||
#[weight = $weight]
|
||||
$fn_vis fn $fn_name(
|
||||
$origin $( , $(#[$codec_attr])* $param_name : $param )*
|
||||
) $( -> $result )* { $( $impl )* }
|
||||
@@ -436,6 +446,45 @@ macro_rules! decl_module {
|
||||
$($rest)*
|
||||
);
|
||||
};
|
||||
// Add #[weight] if none is defined.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<
|
||||
$trait_instance:ident:
|
||||
$trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
|
||||
>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialize:tt )* }
|
||||
{ $( $on_finalize:tt )* }
|
||||
{ $( $offchain:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$fn_vis:vis fn $fn_name:ident(
|
||||
$from:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)*
|
||||
) $( -> $result:ty )* { $( $impl:tt )* }
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
$crate::decl_module!(@normalize
|
||||
$(#[$attr])*
|
||||
pub struct $mod_type<
|
||||
$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?
|
||||
>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $( $deposit_event )* }
|
||||
{ $( $on_initialize )* }
|
||||
{ $( $on_finalize )* }
|
||||
{ $( $offchain )* }
|
||||
[ $($t)* ]
|
||||
$(#[doc = $doc_attr])*
|
||||
#[weight = $crate::dispatch::TransactionWeight::default()]
|
||||
$fn_vis fn $fn_name(
|
||||
$from $(, $(#[$codec_attr])* $param_name : $param )*
|
||||
) $( -> $result )* { $( $impl )* }
|
||||
$($rest)*
|
||||
);
|
||||
};
|
||||
// Ignore any ident which is not `origin` with type `T::Origin`.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -446,6 +495,7 @@ macro_rules! decl_module {
|
||||
{ $( $offchain:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$(#[weight = $weight:expr])?
|
||||
$fn_vis:vis fn $fn_name:ident(
|
||||
$origin:ident : T::Origin $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)*
|
||||
) $( -> $result:ty )* { $( $impl:tt )* }
|
||||
@@ -457,6 +507,7 @@ macro_rules! decl_module {
|
||||
not use the `T::Origin` type.)"
|
||||
)
|
||||
};
|
||||
// Ignore any ident which is `origin` but has a type, regardless of the type token itself.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -467,6 +518,7 @@ macro_rules! decl_module {
|
||||
{ $( $offchain:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$(#[weight = $weight:expr])?
|
||||
$fn_vis:vis fn $fn_name:ident(
|
||||
origin : $origin:ty $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)*
|
||||
) $( -> $result:ty )* { $( $impl:tt )* }
|
||||
@@ -478,6 +530,7 @@ macro_rules! decl_module {
|
||||
not use the `T::Origin` type.)"
|
||||
)
|
||||
};
|
||||
// Add root if no origin is defined.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -488,6 +541,7 @@ macro_rules! decl_module {
|
||||
{ $( $offchain:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$(#[weight = $weight:expr])?
|
||||
$fn_vis:vis fn $fn_name:ident(
|
||||
$( $(#[$codec_attr:ident])* $param_name:ident : $param:ty),*
|
||||
) $( -> $result:ty )* { $( $impl:tt )* }
|
||||
@@ -501,17 +555,18 @@ macro_rules! decl_module {
|
||||
{ $( $on_initialize )* }
|
||||
{ $( $on_finalize )* }
|
||||
{ $( $offchain )* }
|
||||
[
|
||||
$($t)*
|
||||
$(#[doc = $doc_attr])*
|
||||
$fn_vis fn $fn_name(
|
||||
root $( , $(#[$codec_attr])* $param_name : $param )*
|
||||
) $( -> $result )* { $( $impl )* }
|
||||
{ $($instance: $instantiable)? }
|
||||
]
|
||||
[ $($t)* ]
|
||||
|
||||
$(#[doc = $doc_attr])*
|
||||
$(#[weight = $weight])?
|
||||
$fn_vis fn $fn_name(
|
||||
root $( , $(#[$codec_attr])* $param_name : $param )*
|
||||
) $( -> $result )* { $( $impl )* }
|
||||
|
||||
$($rest)*
|
||||
);
|
||||
};
|
||||
// Last normalize step. Triggers `@imp` expansion which is the real expansion.
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
|
||||
@@ -686,6 +741,7 @@ macro_rules! decl_module {
|
||||
{}
|
||||
};
|
||||
|
||||
// Expansion for root dispatch functions with no specified result type.
|
||||
(@impl_function
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
|
||||
$origin_ty:ty;
|
||||
@@ -700,6 +756,7 @@ macro_rules! decl_module {
|
||||
}
|
||||
};
|
||||
|
||||
// Expansion for root dispatch functions with explicit return types.
|
||||
(@impl_function
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
|
||||
$origin_ty:ty;
|
||||
@@ -715,6 +772,7 @@ macro_rules! decl_module {
|
||||
}
|
||||
};
|
||||
|
||||
// Expansion for _origin_ dispatch functions with no return type.
|
||||
(@impl_function
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
|
||||
$origin_ty:ty;
|
||||
@@ -733,6 +791,7 @@ macro_rules! decl_module {
|
||||
}
|
||||
};
|
||||
|
||||
// Expansion for _origin_ dispatch functions with explicit return type.
|
||||
(@impl_function
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
|
||||
$origin_ty:ty;
|
||||
@@ -868,6 +927,7 @@ macro_rules! decl_module {
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident {
|
||||
$(
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
#[weight = $weight:expr]
|
||||
$fn_vis:vis fn $fn_name:ident(
|
||||
$from:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty)*
|
||||
) $( -> $result:ty )* { $( $impl:tt )* }
|
||||
@@ -908,7 +968,6 @@ macro_rules! decl_module {
|
||||
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
|
||||
$( $offchain )*
|
||||
}
|
||||
|
||||
$crate::decl_module! {
|
||||
@impl_deposit_event
|
||||
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
|
||||
@@ -951,6 +1010,18 @@ macro_rules! decl_module {
|
||||
)*
|
||||
}
|
||||
|
||||
// Implement weight calculation function for Call
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Weighable
|
||||
for $call_type<$trait_instance $(, $instance)?>
|
||||
{
|
||||
fn weight(&self, _len: usize) -> $crate::dispatch::Weight {
|
||||
match self {
|
||||
$( $call_type::$fn_name(..) => $crate::dispatch::Weighable::weight(&$weight, _len), )*
|
||||
$call_type::__PhantomItem(_, _) => { unreachable!("__PhantomItem should never be used.") },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// manual implementation of clone/eq/partialeq because using derive erroneously requires
|
||||
// clone/eq/partialeq from T.
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Clone
|
||||
@@ -1072,14 +1143,19 @@ macro_rules! impl_outer_dispatch {
|
||||
$camelcase ( $crate::dispatch::CallableCallFor<$camelcase> )
|
||||
,)*
|
||||
}
|
||||
impl $crate::dispatch::Weighable for $call_type {
|
||||
fn weight(&self, len: usize) -> $crate::dispatch::Weight {
|
||||
match self {
|
||||
$( $call_type::$camelcase(call) => call.weight(len), )*
|
||||
}
|
||||
}
|
||||
}
|
||||
impl $crate::dispatch::Dispatchable for $call_type {
|
||||
type Origin = $origin;
|
||||
type Trait = $call_type;
|
||||
fn dispatch(self, origin: $origin) -> $crate::dispatch::Result {
|
||||
match self {
|
||||
$(
|
||||
$call_type::$camelcase(call) => call.dispatch(origin),
|
||||
)*
|
||||
$( $call_type::$camelcase(call) => call.dispatch(origin), )*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1271,6 +1347,7 @@ mod tests {
|
||||
fn aux_0(_origin) -> Result { unreachable!() }
|
||||
fn aux_1(_origin, #[compact] _data: u32) -> Result { unreachable!() }
|
||||
fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() }
|
||||
#[weight = TransactionWeight::Basic(10, 100)]
|
||||
fn aux_3() -> Result { unreachable!() }
|
||||
fn aux_4(_data: i32) -> Result { unreachable!() }
|
||||
fn aux_5(_origin, _data: i32, #[compact] _data2: u32) -> Result { unreachable!() }
|
||||
@@ -1278,6 +1355,9 @@ mod tests {
|
||||
fn on_initialize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_initialize") } }
|
||||
fn on_finalize(n: T::BlockNumber) { if n.into() == 42 { panic!("on_finalize") } }
|
||||
fn offchain_worker() {}
|
||||
|
||||
#[weight = TransactionWeight::Max]
|
||||
fn weighted() { unreachable!() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1342,6 +1422,11 @@ mod tests {
|
||||
]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
FunctionMetadata {
|
||||
name: DecodeDifferent::Encode("weighted"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
];
|
||||
|
||||
struct TraitImpl {}
|
||||
@@ -1396,4 +1481,14 @@ mod tests {
|
||||
fn on_finalize_should_work() {
|
||||
<Module<TraitImpl> as OnFinalize<u32>>::on_finalize(42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weight_should_attach_to_call_enum() {
|
||||
// max weight. not dependent on input.
|
||||
assert_eq!(Call::<TraitImpl>::weighted().weight(100), 3 * 1024 * 1024);
|
||||
// default weight.
|
||||
assert_eq!(Call::<TraitImpl>::aux_0().weight(5), 5 /*tx-len*/);
|
||||
// custom basic
|
||||
assert_eq!(Call::<TraitImpl>::aux_3().weight(5), 10 + 100 * 5 );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user