In the main lib.rs
of substrate's runtime, (and also in the template node) there are several version attributes which can be changed - I'm guessing for tracking various build versions - but it's not clear how we are to use these in our own projects.
1) What are they for? What are the expectations for incrementing these in our own projects?
2) Are any one of these or combination intended to indicate incompatibility with a prior version of our runtimes, for example an incrementation of this indicates that the newer version is not compatible for storage, consensus or some other aspect that might be expected to cause a fork in the network?
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node"),
impl_name: create_runtime_str!("substrate-node"),
authoring_version: 10,
spec_version: 99,
impl_version: 104,
apis: RUNTIME_API_VERSIONS,
};
Runtime versioning is an important part of the "forkless runtime upgrade" feature of Substrate based blockchains.
From
core/sr-version
at the time of this post:spec_version
is used to signify whether consensus-critical logic has changed, whileimpl_version
is used to signify changes which will not affect consensus in the network. For example, if the behavior of a function changes in the runtime, you must increment thespec_version
to note that this version of the runtime will not come to consensus with another version of the runtime. Whereas, if there was only an optimization made to a function, but the resulting output is the same, then only theimpl_version
needs to be bumped.Using the
spec_version
, a node is able to determine whether the native version of the runtime (the native executable actually running the node) matches the Wasm version of the runtime (which is stored on-chain and the network has come to consensus with).In the case where the native
spec_name
,authoring_version
, andspec_version
of the runtime matches the versions of the Wasm runtime, the native runtime is used instead of the Wasm runtime since it is faster to execute. In the case where thespec_version
does not match exactly, the node will fall back to use the Wasm version of the runtime, ensuring that the node stays in consensus with the rest of the network.If you want to follow the code path where this happens, you can start in
core/sr-version
.Then if you go into
core/executor/native_executor.rs
, you will see thecan_call_with
function is used to determine if the native runtime can be used.Edit: It is important to note that block construction execution engine always defaults to Wasm, while the importing execution engine tries to use native if possible, using the logic above.