-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
Please add some documentation with examples to the crate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general looking really good. It ended much better and easier than I had imagined, nice!
I added some comments on stuff that still needs to improved.
Ty :)
f9c97f6
to
f5c0a38
Compare
Related to issue paritytech#11577 Add support for multiple versions of a Runtime API. The purpose is to have one main version of the API, which is considered stable and multiple unstable (aka staging) ones. How it works =========== Some methods of the API trait can be tagged with `#[api_version(N)]` attribute where N is version number bigger than the main one. Let's call them **staging methods** for brevity. The implementor of the API decides which version to implement. Example (from paritytech#11577 (comment)): ``` decl_runtime_apis! { #{api_version(10)] trait Test { fn something() -> Vec<u8>; #[api_version(11)] fn new_cool_function() -> u32; } } ``` ``` impl_runtime_apis! { #[api_version(11)] impl Test for Runtime { fn something() -> Vec<u8> { vec![1, 2, 3] } fn new_cool_function() -> u32 { 10 } } } ``` Version safety checks (currently not implemented) ================================================= By default in the API trait all staging methods has got default implementation calling `unimplemented!()`. This is a problem because if the developer wants to implement version 11 in the example above and forgets to add `fn new_cool_function()` in `impl_runtime_apis!` the runtime will crash when the function is executed. Ideally a compilation error should be generated in such cases. TODOs ===== Things not working well at the moment: [ ] Version safety check [ ] Integration tests of `primitives/api` are messed up a bit. More specifically `primitives/api/test/tests/decl_and_impl.rs` [ ] Integration test covering the new functionality. [ ] Some duplicated code
Code review feedback and formatting Co-authored-by: asynchronous rob <rphmeier@gmail.com>
Applying suggestions from @bkchr
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general looking really good! Just some last nitpicks
primitives/api/test/tests/ui/method_ver_lower_than_trait_ver.stderr
Outdated
Show resolved
Hide resolved
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some last nitpicks, otherwise looks nice.
decl.items = decl | ||
.items | ||
.iter_mut() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decl.items = decl | |
.items | |
.iter_mut() | |
decl | |
.items | |
.iter() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iter_mut()
here should stay. The method is modified in the for_each()
.
Ty for all the hard work @tdimitrov :) (And especially going through all of this with me 😅) |
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Thanks for the kind words, @bkchr
On the contrary - it was fun and I learned a lot! |
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
* Runtime API versioning Related to issue paritytech#11577 Add support for multiple versions of a Runtime API. The purpose is to have one main version of the API, which is considered stable and multiple unstable (aka staging) ones. How it works =========== Some methods of the API trait can be tagged with `#[api_version(N)]` attribute where N is version number bigger than the main one. Let's call them **staging methods** for brevity. The implementor of the API decides which version to implement. Example (from paritytech#11577 (comment)): ``` decl_runtime_apis! { #{api_version(10)] trait Test { fn something() -> Vec<u8>; #[api_version(11)] fn new_cool_function() -> u32; } } ``` ``` impl_runtime_apis! { #[api_version(11)] impl Test for Runtime { fn something() -> Vec<u8> { vec![1, 2, 3] } fn new_cool_function() -> u32 { 10 } } } ``` Version safety checks (currently not implemented) ================================================= By default in the API trait all staging methods has got default implementation calling `unimplemented!()`. This is a problem because if the developer wants to implement version 11 in the example above and forgets to add `fn new_cool_function()` in `impl_runtime_apis!` the runtime will crash when the function is executed. Ideally a compilation error should be generated in such cases. TODOs ===== Things not working well at the moment: [ ] Version safety check [ ] Integration tests of `primitives/api` are messed up a bit. More specifically `primitives/api/test/tests/decl_and_impl.rs` [ ] Integration test covering the new functionality. [ ] Some duplicated code * Update primitives/api/proc-macro/src/impl_runtime_apis.rs Code review feedback and formatting Co-authored-by: asynchronous rob <rphmeier@gmail.com> * Code review feedback Applying suggestions from @bkchr * fmt * Apply suggestions from code review Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Code review feedback * dummy trait -> versioned trait * Implement only versioned traits (not compiling) * Remove native API calls (still not compiling) * fmt * Fix compilation * Comments * Remove unused code * Remove native runtime tests * Remove unused code * Fix UI tests * Code review feedback * Code review feedback * attribute_names -> common * Rework `append_api_version` * Code review feedback * Apply suggestions from code review Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Code review feedback * Code review feedback * Code review feedback * Use type alias for the default trait - doesn't compile * Fixes * Better error for `method_api_ver < trait_api_version` * fmt * Rework how we call runtime functions * Update UI tests * Fix warnings * Fix doctests * Apply suggestions from code review Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Fix formatting and small compilation errors * Update primitives/api/proc-macro/src/impl_runtime_apis.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: asynchronous rob <rphmeier@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <info@kchr.de>
Related to issue #11577
Add support for multiple versions of a Runtime API. The purpose is to have one main version of the API, which is considered stable and multiple extensions (also referred as versioned methods) to it. Effectively from substrate point of view these are just different versions of the same API. It's up to the implementor to add semantics.
How it works
Some methods of the API trait can be tagged with
#[api_version(N)]
attribute where N is version number bigger than the main one. Let's call them versioned methods for brevity. Then the implementor of the API decides which version to implement.Example (from #11577 (comment)):
Version safety checks
By default in the API trait all staging methods has got a default implementation calling
unimplemented!()
. This is a problem because if the developer wants to implement version 11 in the example above and forgets to addfn new_cool_function()
inimpl_runtime_apis!
the runtime will crash when the function is executed.To overcome this
decl_runtime_apis!
generates multiple dummy traits for each version it finds in the declaration. These traits contain all required methods and have no default implementations. Then when the developer implements a specific version a dummy implementation of a versioned trait (besides the actual one) is generated. If the developer has forgotten to add a method - a compilation error will be generated.TODOs
decl_runtime_apis!
should generate an array with all valid versions.impl_runtime_apis!
should return one of these versions instead of what's in its attribute so that a nonexistent version can't be implemented by mistake.primitives/api
are messed up a bit. More specificallyprimitives/api/test/tests/decl_and_impl.rs
IntegrationUI test covering the new functionality.