1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// This file is part of Soil.
// Copyright (C) Soil contributors.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0
//! Substrate runtime interface
//!
//! This module provides types, traits and macros around runtime interfaces. A runtime interface is
//! a fixed interface between a Substrate runtime (also called the "guest") and a Substrate node
//! (also called the "host"). For a native runtime the interface maps to direct function calls of
//! the implementation. For a non-native runtime the interface maps to an external function call.
//! These external functions are exported by the runtime and they map to the same implementation
//! as the native calls, just with some extra code to marshal them through the FFI boundary.
//!
//! # Using a type in a runtime interface
//!
//! Every argument type and return type must be wrapped in a marker newtype specifying the
//! marshalling strategy used to pass the value through the FFI boundary between the host
//! and the runtime. The only exceptions to this rule are a couple of basic, primitive types
//! which can be passed directly through the FFI boundary and which don't require any special
//! handling besides a straightforward, direct conversion.
//!
//! You can find the strategy wrapper types in the [`pass_by`] module.
//!
//! The newtype wrappers are automatically stripped away when the function is called
//! and applied when the function returns by the `runtime_interface` macro.
//!
//! # Declaring a runtime interface
//!
//! Declaring a runtime interface is similar to declaring a trait in Rust:
//!
//! ```ignore
//! # mod wrapper {
//! # use subsoil::runtime_interface::pass_by::PassFatPointerAndRead;
//!
//! #[subsoil::runtime_interface::runtime_interface]
//! trait RuntimeInterface {
//! fn some_function(value: PassFatPointerAndRead<&[u8]>) -> bool {
//! value.iter().all(|v| *v > 125)
//! }
//! }
//! # }
//! ```
//!
//! For more information on declaring a runtime interface, see
//! [`#[runtime_interface]`](attr.runtime_interface.html).
pub use cratewasm_interface;
pub use cratestd;
/// Attribute macro for transforming a trait declaration into a runtime interface.
///
/// A runtime interface is a fixed interface between a Substrate compatible runtime and the
/// native node. 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.
///
/// The macro expects the runtime interface declaration as trait declaration:
///
/// ```ignore
/// # mod wrapper {
/// # use subsoil::runtime_interface::runtime_interface;
/// # use subsoil::runtime_interface::pass_by::{PassFatPointerAndDecode, PassFatPointerAndRead, AllocateAndReturnFatPointer};
///
/// #[runtime_interface]
/// trait Interface {
/// /// A function that can be called from native/wasm.
/// ///
/// /// The implementation given to this function is only compiled on native.
/// fn call(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnFatPointer<Vec<u8>> {
/// // Here you could call some rather complex code that only compiles on native or
/// // is way faster in native than executing it in wasm.
/// Vec::new()
/// }
/// /// Call function, but different version.
/// ///
/// /// For new runtimes, only function with latest version is reachable.
/// /// But old version (above) is still accessible for old runtimes.
/// /// Default version is 1.
/// #[version(2)]
/// fn call(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnFatPointer<Vec<u8>> {
/// // Here you could call some rather complex code that only compiles on native or
/// // is way faster in native than executing it in wasm.
/// [17].to_vec()
/// }
///
/// /// Call function, different version and only being registered.
/// ///
/// /// This `register_only` version is only being registered, aka exposed to the runtime,
/// /// but the runtime will still use the version 2 of this function. This is useful for when
/// /// new host functions should be introduced. Adding new host functions requires that all
/// /// nodes have the host functions available, because otherwise they fail at instantiation
/// /// of the runtime. With `register_only` the function will not be used when compiling the
/// /// runtime, but it will already be there for a future version of the runtime that will
/// /// switch to using these host function.
/// #[version(3, register_only)]
/// fn call(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnFatPointer<Vec<u8>> {
/// // Here you could call some rather complex code that only compiles on native or
/// // is way faster in native than executing it in wasm.
/// [18].to_vec()
/// }
///
/// /// A function can take a `&self` or `&mut self` argument to get access to the
/// /// `Externalities`. (The generated method does not require
/// /// this argument, so the function can be called just with the `optional` argument)
/// fn set_or_clear(&mut self, optional: PassFatPointerAndDecode<Option<Vec<u8>>>) {
/// match optional {
/// Some(value) => self.set_storage([1, 2, 3, 4].to_vec(), value),
/// None => self.clear_storage(&[1, 2, 3, 4]),
/// }
/// }
///
/// /// A function can be gated behind a configuration (`cfg`) attribute.
/// /// To prevent ambiguity and confusion about what will be the final exposed host
/// /// functions list, conditionally compiled functions can't be versioned.
/// /// That is, conditionally compiled functions with `version`s greater than 1
/// /// are not allowed.
/// #[cfg(feature = "experimental-function")]
/// fn gated_call(data: PassFatPointerAndRead<&[u8]>) -> AllocateAndReturnFatPointer<Vec<u8>> {
/// [42].to_vec()
/// }
/// }
/// # }
/// ```
///
/// # Argument and return types
///
/// Every argument type and return type must be wrapped in a marker newtype specifying the
/// marshalling strategy used to pass the value through the FFI boundary between the host
/// and the runtime. The only exceptions to this rule are a couple of basic, primitive types
/// which can be passed directly through the FFI boundary and which don't require any special
/// handling besides a straightforward, direct conversion.
///
/// The following table documents those types which can be passed between the host and the
/// runtime without a marshalling strategy wrapper:
///
/// | Type | FFI type | Conversion |
/// |----|----|----|
/// | `u8` | `u32` | zero-extended to 32-bits |
/// | `u16` | `u32` | zero-extended to 32-bits |
/// | `u32` | `u32` | `Identity` |
/// | `u64` | `u64` | `Identity` |
/// | `i8` | `i32` | sign-extended to 32-bits |
/// | `i16` | `i32` | sign-extended to 32-bits |
/// | `i32` | `i32` | `Identity` |
/// | `i64` | `i64` | `Identity` |
/// | `bool` | `u32` | `if v { 1 } else { 0 }` |
/// | `*const T` | `u32` | `Identity` |
///
/// `Identity` means that the value is passed as-is directly in a bit-exact fashion.
///
/// You can find the strategy wrapper types in the [`pass_by`] module.
///
/// The newtype wrappers are automatically stripped away when the function is called
/// and applied when the function returns by the `runtime_interface` macro.
///
/// # Wasm only interfaces
///
/// Some interfaces are only required from within the wasm runtime e.g. the allocator
/// interface. To support this, the macro can be called like `#[runtime_interface(wasm_only)]`.
/// This instructs the macro to make two significant changes to the generated code:
///
/// 1. The generated functions are not callable from the native side.
/// 2. The trait as shown above is not implemented for [`Externalities`] and is instead
/// implemented for `FunctionContext` (from `sp-wasm-interface`).
///
/// # Disable tracing
/// By adding `no_tracing` to the list of options you can prevent the wasm-side interface from
/// generating the default `sp-tracing`-calls. Note that this is rarely needed but only meant
/// for the case when that would create a circular dependency. You usually _do not_ want to add
/// this flag, as tracing doesn't cost you anything by default anyways (it is added as a no-op)
/// but is super useful for debugging later.
pub use runtime_interface;
pub use crate;
pub use codec;
pub use alloc;
pub
pub use ;
/// Something that can be used by the runtime interface as type to communicate between the runtime
/// and the host.
///
/// Every type that should be used in a runtime interface function signature needs to implement
/// this trait.
/// A raw pointer that can be used in a runtime interface function signature.
pub type Pointer<T> = *mut T;
/// A raw pointer that can be used in a runtime interface function signature.
pub type Pointer<T> = cratePointer;