Skip to main content
Zondax Github LinkZondax Github Link
Theme SwitchTheme Switch

Rewrite of core primitives crates

As a proof of concept, we have selected some components to show how our development process can be effectively used to progressively evolve the existing Parity node. This provides the opportunity to use the aforementioned libraries , while ensuring that our project structure and tooling are as useful as planned.

Selection of the replaced components

While analyzing the code stability we observed that some important crates in the Polkadot node depend on primitives modules. The primitives are mostly re-exports of types that are defined in Substrate but with a concrete type bound. This makes the primitives crates a good target to get an insight on how this process is going to be. We selected two primitives crates as follows:

Module replacement

The core-primitives component was relatively easy to re-write as it is essentially a collection of type aliases and some re-exports with a proper type bound. We discovered that type aliases are difficult as they are not really an instance but a new name for a type. In C++ there is a using keyword, but this is not supported by the cxx crate. This module re-exports important blockchain primitives.

The parachain/primitives module is more complex as it defines various structs, though many of them are just wrappers around Rust's primitives types like integers.

We emphasize that our current re-write -- the core-primitives and parachain repositories in mayon/crates -- mostly interfaces some types to C++, so that other C++ modules can import them. We believe that it is better to implement an FFI layer which interfaces with the definitions of imported types. This implies that at some point we will need to re-write the most used substrate modules and include them in our code base. We started doing this for the sp-primitives/runtime module, in order to define the generic types for some elements that the core-primitives re-export from that crate. This re-write is not expected to cover all the modules from a substrate dependency but the ones that are required by the primitives definitions in Polkadot.

Substrate design separates Data from their functionality. This decouples functionality from the concrete type. This facilitates our implementation making it clear what are the methods our header instance provides, and that there would no be compilation errors from Rust due to differences between a Header instance.