I am struggling with #[runtime_interface]
the whole day. here is the Runtime Interface Trait Defination, the expanded macro is too long to paste here, here is a expanded macro. I have lots of questions here.
- From the runtime_interface rust doc:
This interface is callable from a native and a wasm runtime. The macro will generate the corresponding code for the native implementation and the code for calling from the wasm side to the native implementation.
What I understand here(If wrong, please correct me):
- This HostFunction will be registered in the executor, this belongs to the node side.
pub struct HostFunctions;
impl proc_macro_runtime_interface::sp_wasm_interface::HostFunctions for HostFunctions{...}
- I do not know what
&mut dyn proc_macro_runtime_interface::Externalities
is, but I guess this is for the runtime side. Can somebody explain how to understand theExternalities
here?
#[cfg(feature = "std")]
impl DvmExt for &mut dyn proc_macro_runtime_interface::Externalities {...}
- Other generated code(part of it). I guess this is
the code for calling from the wasm side to the native implementation.
I noticed that this function usesproc_macro_runtime_interface::with_externalities(...)
and I found Use sp_externalities::with_externalities. But, I am still don't know how this function call from wasm side to the native side.
#[cfg(feature = "std")]
/// An `Evm` event proxied by the runtime to this host function.
/// evm -> runtime -> host.
fn evm_event_version_1(event: Vec<u8>) {
{
use ::tracing::__macro_support::Callsite as _;
static CALLSITE: ::tracing::__macro_support::MacroCallsite = {
use ::tracing::__macro_support::MacroCallsite;
static META: ::tracing::Metadata<'static> = {
::tracing_core::metadata::Metadata::new(
"evm_event_version_1",
"dp_evm_trace_ext::dvm_ext",
::tracing::Level::TRACE,
Some("primitives/evm-trace/ext/src/lib.rs"),
Some(31u32),
Some("dp_evm_trace_ext::dvm_ext"),
::tracing_core::field::FieldSet::new(
&[],
::tracing_core::callsite::Identifier(&CALLSITE),
),
::tracing::metadata::Kind::SPAN,
)
};
MacroCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&& ::tracing::Level::TRACE <= ::tracing::level_filters::LevelFilter::current()
&& {
interest = CALLSITE.interest();
!interest.is_never()
}
&& CALLSITE.is_enabled(interest)
{
let meta = CALLSITE.metadata();
::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) })
} else {
let span = CALLSITE.disabled_span();
{};
span
}
}
.in_scope(|| {
proc_macro_runtime_interface::with_externalities(|mut __externalities__| {
DvmExt::evm_event_version_1(&mut __externalities__, event)
})
.expect("`evm_event_version_1` called outside of an Externalities-provided environment.")
})
}
- After all the above things are done. What is the common way to call from the wasm side to the native side or the native side to the wasm side? Is there any example for beginners to understand?