runtime-interface: Implement register_only functions (#10640)

* runtime-interface: Implement `register_only` functions

The runtime interface supports versioning of functions. Currently, if you add a new function it will
be used by the runtime automatically. This results in requiring all nodes of a network to upgrade
before the runtime is upgraded, otherwise they will fail to instantiate the new runtime because of
missing host functions. This pr introduces `register_only` functions. This can be used when a new
runtime interface function should be introduced, but the actual usage can be deferred. This means
that nodes will have the host function for this, but the runtime will still use the old version of
the function when being compiled for wasm. However, when a runtime is enacted that uses the new host
function, the "old nodes" will already have the host function and will continue to work.

* Update primitives/runtime-interface/src/lib.rs

Co-authored-by: cheme <emericchevalier.pro@gmail.com>

* Update primitives/runtime-interface/proc-macro/src/utils.rs

Co-authored-by: cheme <emericchevalier.pro@gmail.com>

* FMT

Co-authored-by: cheme <emericchevalier.pro@gmail.com>
This commit is contained in:
Bastian Köcher
2022-01-15 11:46:20 +01:00
committed by GitHub
parent c33fb8db76
commit a534274c6f
6 changed files with 155 additions and 68 deletions
@@ -52,7 +52,7 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool, tracing: bool) -> Res
let runtime_interface = get_runtime_interface(trait_def)?;
// latest version dispatch
let token_stream: Result<TokenStream> = runtime_interface.latest_versions().try_fold(
let token_stream: Result<TokenStream> = runtime_interface.latest_versions_to_call().try_fold(
TokenStream::new(),
|mut t, (latest_version, method)| {
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
@@ -45,19 +45,18 @@ use std::iter::Iterator;
/// implementations for the host functions on the host.
pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
let trait_name = &trait_def.ident;
let extern_host_function_impls = get_runtime_interface(trait_def)?.latest_versions().try_fold(
TokenStream::new(),
|mut t, (version, method)| {
let extern_host_function_impls = get_runtime_interface(trait_def)?
.latest_versions_to_call()
.try_fold(TokenStream::new(), |mut t, (version, method)| {
t.extend(generate_extern_host_function(method, version, trait_name)?);
Ok::<_, Error>(t)
},
)?;
let exchangeable_host_functions = get_runtime_interface(trait_def)?
.latest_versions()
.try_fold(TokenStream::new(), |mut t, (_, m)| {
t.extend(generate_exchangeable_host_function(m)?);
Ok::<_, Error>(t)
})?;
let exchangeable_host_functions = get_runtime_interface(trait_def)?
.latest_versions_to_call()
.try_fold(TokenStream::new(), |mut t, (_, m)| {
t.extend(generate_exchangeable_host_function(m)?);
Ok::<_, Error>(t)
})?;
let host_functions_struct = generate_host_functions_struct(trait_def, is_wasm_only)?;
Ok(quote! {