-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Introduce #[pallet::call_index] attribute to dispatchables #11381
Changes from all commits
687d67c
85f43f0
9932c89
113f1ff
7a978df
e2bc4a1
73cf866
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1645,6 +1645,15 @@ pub mod pallet_prelude { | |
/// used using `#[pallet::compact]`, function must return `DispatchResultWithPostInfo` or | ||
/// `DispatchResult`. | ||
/// | ||
/// Each dispatchable may also be annotated with the `#[pallet::call_index($idx)]` attribute, | ||
/// which defines and sets the codec index for the dispatchable function in the `Call` enum. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you briefly add a description here of what happens if you use the call index in some placed, but not in others? Can we make it so that call index must be used everywhere or nowhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, probably call index should just be mandatory. We could allow users to ignore it if they use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the spirit of keeping the FRAME boilerplate minimal, I don't think mandating call-indices should be mandatory. I like how it works in |
||
/// | ||
/// All call indexes start from 0, until it encounters a dispatchable function with a defined | ||
/// call index. The dispatchable function that lexically follows the function with a defined | ||
/// call index will have that call index, but incremented by 1, e.g. if there are 3 | ||
/// dispatchable functions `fn foo`, `fn bar` and `fn qux` in that order, and only `fn bar` has | ||
/// a call index of 10, then `fn qux` will have an index of 11, instead of 1. | ||
/// | ||
/// All arguments must implement `Debug`, `PartialEq`, `Eq`, `Decode`, `Encode`, `Clone`. For | ||
/// ease of use, bound the trait `Member` available in frame_support::pallet_prelude. | ||
/// | ||
|
@@ -1658,16 +1667,18 @@ pub mod pallet_prelude { | |
/// **WARNING**: modifying dispatchables, changing their order, removing some must be done with | ||
/// care. Indeed this will change the outer runtime call type (which is an enum with one | ||
/// variant per pallet), this outer runtime call can be stored on-chain (e.g. in | ||
/// pallet-scheduler). Thus migration might be needed. | ||
/// pallet-scheduler). Thus migration might be needed. To mitigate against some of this, the | ||
/// `#[pallet::call_index($idx)]` attribute can be used to fix the order of the dispatchable so | ||
/// that the `Call` enum encoding does not change after modification. | ||
/// | ||
/// ### Macro expansion | ||
/// | ||
/// The macro create an enum `Call` with one variant per dispatchable. This enum implements: | ||
/// The macro creates an enum `Call` with one variant per dispatchable. This enum implements: | ||
/// `Clone`, `Eq`, `PartialEq`, `Debug` (with stripped implementation in `not("std")`), | ||
/// `Encode`, `Decode`, `GetDispatchInfo`, `GetCallName`, `UnfilteredDispatchable`. | ||
/// | ||
/// The macro implement on `Pallet`, the `Callable` trait and a function `call_functions` which | ||
/// returns the dispatchable metadatas. | ||
/// The macro implement the `Callable` trait on `Pallet` and a function `call_functions` which | ||
/// returns the dispatchable metadata. | ||
/// | ||
/// # Extra constants: `#[pallet::extra_constants]` optional | ||
/// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#[frame_support::pallet] | ||
mod pallet { | ||
use frame_support::pallet_prelude::DispatchResultWithPostInfo; | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config {} | ||
|
||
#[pallet::pallet] | ||
pub struct Pallet<T>(core::marker::PhantomData<T>); | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
#[pallet::weight(0)] | ||
#[pallet::call_index(10)] | ||
pub fn foo(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
|
||
#[pallet::weight(0)] | ||
#[pallet::call_index(10)] | ||
pub fn bar(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
} | ||
} | ||
|
||
fn main() { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error: Call indices are conflicting: Both functions foo and bar are at index 10 | ||
--> tests/pallet_ui/call_conflicting_indices.rs:15:10 | ||
| | ||
15 | pub fn foo(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
| ^^^ | ||
|
||
error: Call indices are conflicting: Both functions foo and bar are at index 10 | ||
--> tests/pallet_ui/call_conflicting_indices.rs:19:10 | ||
| | ||
19 | pub fn bar(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
| ^^^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#[frame_support::pallet] | ||
mod pallet { | ||
use frame_support::pallet_prelude::DispatchResultWithPostInfo; | ||
use frame_system::pallet_prelude::OriginFor; | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config {} | ||
|
||
#[pallet::pallet] | ||
pub struct Pallet<T>(core::marker::PhantomData<T>); | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
#[pallet::weird_attr] | ||
pub fn foo(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
} | ||
} | ||
|
||
fn main() { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
error: expected `weight` or `call_index` | ||
--> tests/pallet_ui/call_invalid_attr.rs:14:13 | ||
| | ||
14 | #[pallet::weird_attr] | ||
| ^^^^^^^^^^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#[frame_support::pallet] | ||
mod pallet { | ||
use frame_support::pallet_prelude::DispatchResultWithPostInfo; | ||
use frame_system::pallet_prelude::OriginFor; | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config {} | ||
|
||
#[pallet::pallet] | ||
pub struct Pallet<T>(core::marker::PhantomData<T>); | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
#[pallet::weight(0)] | ||
#[pallet::call_index(256)] | ||
pub fn foo(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
} | ||
} | ||
|
||
fn main() { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
error: number too large to fit in target type | ||
--> tests/pallet_ui/call_invalid_index.rs:15:24 | ||
| | ||
15 | #[pallet::call_index(256)] | ||
| ^^^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#[frame_support::pallet] | ||
mod pallet { | ||
use frame_support::pallet_prelude::DispatchResultWithPostInfo; | ||
use frame_system::pallet_prelude::OriginFor; | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config {} | ||
|
||
#[pallet::pallet] | ||
pub struct Pallet<T>(core::marker::PhantomData<T>); | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
#[pallet::weight(0)] | ||
#[pallet::call_index(1)] | ||
#[pallet::call_index(2)] | ||
pub fn foo(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
} | ||
} | ||
|
||
fn main() { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
error: Invalid pallet::call, too many call_index attributes given | ||
--> tests/pallet_ui/call_multiple_call_index.rs:17:7 | ||
| | ||
17 | pub fn foo(origin: OriginFor<T>) -> DispatchResultWithPostInfo {} | ||
| ^^ |
Uh oh!
There was an error while loading. Please reload this page.