Files
pezkuwi-subxt/substrate/primitives/runtime-interface
Kian Paimani eaf1bc5633 Introduce Polkadot-Sdk developer_hub (#2102)
This PR introduces the new crate `developer_hub` into the polkadot-sdk
repo. The vision for the developer-hub crate is detailed in [this
document](https://docs.google.com/document/d/1XLLkFNE8v8HLvZpI2rzsa8N2IN1FcKntc8q-Sc4xBAk/edit?usp=sharing).

<img width="1128" alt="Screenshot 2023-11-02 at 10 45 48"
src="https://github.com/paritytech/polkadot-sdk/assets/5588131/1e12b60f-fef5-42c4-8503-a3ba234077c3">


Other than adding the new crate, it also does the following: 

* Remove the `substrate` crate, as there is now a unique umbrella crate
for multiple things in `developer_hub::polkadot_sdk`.
* (backport candidate) A minor change to `frame-support` macros that
allows `T::RuntimeOrigin` to also be acceptable as the origin type.
* (backport candidate) A minor change to `frame-system` that allows us
to deposit events at genesis because now the real genesis config is
generated via wasm, and we can safely assume `cfg!(feature = "std")`
means only testing. related to #62.
* (backport candidate) Introduces a small `read_events_for_pallet` to
`frame_system` for easier event reading in tests.
* From https://github.com/paritytech/polkadot-sdk-docs/issues/31, it
takes action on improving the `pallet::call` docs.
* From https://github.com/paritytech/polkadot-sdk-docs/issues/31, it
takes action on improving the `UncheckedExtrinsic` docs.

## Way Forward

First, a version of this is deployed temporarily
[here](https://blog.kianenigma.nl/polkadot-sdk/developer_hub/index.html).
I will keep it up to date on a daily basis.

### This Pull Request

I see two ways forward: 

1. We acknowledge that everything in `developer-hub` is going to be WIP,
and merge this asap. We should not yet use links to this crate anywhere.
2. We make this be the feature branch, make PRs against this, and either
gradually backport it, or only merge to master once it is done.

I am personally in favor of option 1. If we stick to option 2, we need a
better way to deploy a staging version of this to gh-pages.

### Issue Tracking

The main issues related to the future of `developer_hub` are: 

- https://github.com/paritytech/polkadot-sdk-docs/issues/31
- https://github.com/paritytech/polkadot-sdk-docs/issues/4
- https://github.com/paritytech/polkadot-sdk-docs/issues/26 
- https://github.com/paritytech/polkadot-sdk-docs/issues/32
- https://github.com/paritytech/polkadot-sdk-docs/issues/36


### After This Pull Request

- [ ] create a redirect for
https://paritytech.github.io/polkadot-sdk/master/substrate/
- [x] analytics 
- [ ] link checker
- [ ] the matter of publishing, and how all of these relative links for
when we do, that is still an open question. There is section on this in
the landing page.
- [ ] updated https://paritytech.github.io/

---------

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
Co-authored-by: Juan Girini <juangirini@gmail.com>
Co-authored-by: bader y <ibnbassem@gmail.com>
Co-authored-by: Sebastian Kunert <skunert49@gmail.com>
Co-authored-by: James Wilson <james@jsdw.me>
Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com>
2023-11-30 12:15:46 +01:00
..
2023-08-29 13:39:41 +02:00
2023-10-24 17:59:38 +02:00
2023-08-29 13:39:41 +02:00
2023-09-04 12:02:32 +03:00

Substrate runtime interface

This crate provides types, traits and macros around runtime interfaces. A runtime interface is a fixed interface between a Substrate runtime and a Substrate node. For a native runtime the interface maps to a direct function call of the implementation. For a wasm runtime the interface maps to an external function call. These external functions are exported by the wasm executor and they map to the same implementation as the native calls.

Using a type in a runtime interface

Any type that should be used in a runtime interface as argument or return value needs to implement [RIType]. The associated type FFIType is the type that is used in the FFI function to represent the actual type. For example [T] is represented by an u64. The slice pointer and the length will be mapped to an u64 value. For more information see this table. The FFI function definition is used when calling from the wasm runtime into the node.

Traits are used to convert from a type to the corresponding RIType::FFIType. Depending on where and how a type should be used in a function signature, a combination of the following traits need to be implemented:

  1. Pass as function argument: [wasm::IntoFFIValue] and [host::FromFFIValue]
  2. As function return value: [wasm::FromFFIValue] and [host::IntoFFIValue]
  3. Pass as mutable function argument: [host::IntoPreallocatedFFIValue]

The traits are implemented for most of the common types like [T], Vec<T>, arrays and primitive types.

For custom types, we provide the PassBy trait and strategies that define how a type is passed between the wasm runtime and the node. Each strategy also provides a derive macro to simplify the implementation.

Performance

To not waste any more performance when calling into the node, not all types are SCALE encoded when being passed as arguments between the wasm runtime and the node. For most types that are raw bytes like Vec<u8>, [u8] or [u8; N] we pass them directly, without SCALE encoding them in front of. The implementation of [RIType] each type provides more information on how the data is passed.

Declaring a runtime interface

Declaring a runtime interface is similar to declaring a trait in Rust:

#[sp_runtime_interface::runtime_interface]
trait RuntimeInterface {
    fn some_function(value: &[u8]) -> bool {
        value.iter().all(|v| *v > 125)
    }
}

For more information on declaring a runtime interface, see #[runtime_interface].

FFI type and conversion

The following table documents how values of types are passed between the wasm and the host side and how they are converted into the corresponding type.

Type FFI type Conversion
u8 u8 Identity
u16 u16 Identity
u32 u32 Identity
u64 u64 Identity
i128 u32 v.as_ptr() (pointer to a 16 byte array)
i8 i8 Identity
i16 i16 Identity
i32 i32 Identity
i64 i64 Identity
u128 u32 v.as_ptr() (pointer to a 16 byte array)
bool u8 if v { 1 } else { 0 }
&str u64 v.len() 32bit << 32 | v.as_ptr() 32bit
&[u8] u64 v.len() 32bit << 32 | v.as_ptr() 32bit
Vec<u8> u64 v.len() 32bit << 32 | v.as_ptr() 32bit
Vec<T> where T: Encode u64 let e = v.encode();

e.len() 32bit << 32 | e.as_ptr() 32bit
&[T] where T: Encode u64 let e = v.encode();

e.len() 32bit << 32 | e.as_ptr() 32bit
[u8; N] u32 v.as_ptr()
*const T u32 Identity
Option<T> u64 let e = v.encode();

e.len() 32bit << 32 | e.as_ptr() 32bit
T where T: PassBy<PassBy=Inner> Depends on inner Depends on inner
T where T: PassBy<PassBy=Codec> u64 v.len() 32bit << 32 | v.as_ptr() 32bit

Identity means that the value is converted directly into the corresponding FFI type.

License: Apache-2.0