Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion substrate/bin/utils/chain-spec-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ pub fn generate_chain_spec_for_runtime(cmd: &RuntimeCmd) -> Result<String, Strin
)?)
},
GenesisBuildAction::Default(DefaultCmd { ref default_config_path }) => {
let caller = GenesisConfigBuilderRuntimeCaller::new(&code[..]);
let caller: GenesisConfigBuilderRuntimeCaller =
GenesisConfigBuilderRuntimeCaller::new(&code[..]);
let default_config = caller
.get_default_config()
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
Expand Down
56 changes: 40 additions & 16 deletions substrate/client/chain-spec/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
//! Substrate chain configurations.
#![warn(missing_docs)]
use crate::{
extension::GetExtension, ChainType, GenesisConfigBuilderRuntimeCaller as RuntimeCaller,
Properties, RuntimeGenesis,
extension::GetExtension, genesis_config_builder::HostFunctions, ChainType,
GenesisConfigBuilderRuntimeCaller as RuntimeCaller, Properties, RuntimeGenesis,
};
use sc_network::config::MultiaddrWithPeerId;
use sc_telemetry::TelemetryEndpoints;
Expand Down Expand Up @@ -122,7 +122,10 @@ impl<G: RuntimeGenesis> GenesisSource<G> {
}
}

impl<G: RuntimeGenesis, E> BuildStorage for ChainSpec<G, E> {
impl<G: RuntimeGenesis, E, HF> BuildStorage for ChainSpec<G, E, HF>
where
HF: HostFunctions,
{
fn assimilate_storage(&self, storage: &mut Storage) -> Result<(), String> {
match self.genesis.resolve()? {
#[allow(deprecated)]
Expand Down Expand Up @@ -158,7 +161,7 @@ impl<G: RuntimeGenesis, E> BuildStorage for ChainSpec<G, E> {
json_blob: RuntimeGenesisConfigJson::Config(config),
code,
}) => {
RuntimeCaller::new(&code[..])
RuntimeCaller::<HF>::new(&code[..])
.get_storage_for_config(config)?
.assimilate_storage(storage)?;
storage
Expand All @@ -169,7 +172,7 @@ impl<G: RuntimeGenesis, E> BuildStorage for ChainSpec<G, E> {
json_blob: RuntimeGenesisConfigJson::Patch(patch),
code,
}) => {
RuntimeCaller::new(&code[..])
RuntimeCaller::<HF>::new(&code[..])
.get_storage_for_patch(patch)?
.assimilate_storage(storage)?;
storage
Expand Down Expand Up @@ -448,23 +451,29 @@ impl<G, E> ChainSpecBuilder<G, E> {
ChainSpec {
client_spec,
genesis: GenesisSource::GenesisBuilderApi(self.genesis_build_action, self.code.into()),
_host_functions: Default::default(),
}
}
}

/// A configuration of a chain. Can be used to build a genesis block.
pub struct ChainSpec<G, E = NoExtension> {
pub struct ChainSpec<G, E = NoExtension, HF = sp_io::SubstrateHostFunctions> {
client_spec: ClientSpec<E>,
genesis: GenesisSource<G>,
_host_functions: PhantomData<HF>,
}

impl<G, E: Clone> Clone for ChainSpec<G, E> {
impl<G, E: Clone, HF> Clone for ChainSpec<G, E, HF> {
fn clone(&self) -> Self {
ChainSpec { client_spec: self.client_spec.clone(), genesis: self.genesis.clone() }
ChainSpec {
client_spec: self.client_spec.clone(),
genesis: self.genesis.clone(),
_host_functions: self._host_functions.clone(),
}
}
}

impl<G, E> ChainSpec<G, E> {
impl<G, E, HF> ChainSpec<G, E, HF> {
/// A list of bootnode addresses.
pub fn boot_nodes(&self) -> &[MultiaddrWithPeerId] {
&self.client_spec.boot_nodes
Expand Down Expand Up @@ -553,6 +562,7 @@ impl<G, E> ChainSpec<G, E> {
ChainSpec {
client_spec,
genesis: GenesisSource::Factory(Arc::new(constructor), code.into()),
_host_functions: Default::default(),
}
}

Expand All @@ -567,14 +577,18 @@ impl<G, E> ChainSpec<G, E> {
}
}

impl<G: serde::de::DeserializeOwned, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
impl<G: serde::de::DeserializeOwned, E: serde::de::DeserializeOwned, HF> ChainSpec<G, E, HF> {
/// Parse json content into a `ChainSpec`
pub fn from_json_bytes(json: impl Into<Cow<'static, [u8]>>) -> Result<Self, String> {
let json = json.into();
let client_spec = json::from_slice(json.as_ref())
.map_err(|e| format!("Error parsing spec file: {}", e))?;

Ok(ChainSpec { client_spec, genesis: GenesisSource::Binary(json) })
Ok(ChainSpec {
client_spec,
genesis: GenesisSource::Binary(json),
_host_functions: Default::default(),
})
}

/// Parse json file into a `ChainSpec`
Expand All @@ -593,7 +607,11 @@ impl<G: serde::de::DeserializeOwned, E: serde::de::DeserializeOwned> ChainSpec<G
let client_spec =
json::from_slice(&bytes).map_err(|e| format!("Error parsing spec file: {}", e))?;

Ok(ChainSpec { client_spec, genesis: GenesisSource::File(path) })
Ok(ChainSpec {
client_spec,
genesis: GenesisSource::File(path),
_host_functions: Default::default(),
})
}
}

Expand All @@ -608,7 +626,10 @@ struct ChainSpecJsonContainer<G, E> {
genesis: Genesis<G>,
}

impl<G: RuntimeGenesis, E: serde::Serialize + Clone + 'static> ChainSpec<G, E> {
impl<G: RuntimeGenesis, E: serde::Serialize + Clone + 'static, HF> ChainSpec<G, E, HF>
where
HF: HostFunctions,
{
fn json_container(&self, raw: bool) -> Result<ChainSpecJsonContainer<G, E>, String> {
let raw_genesis = match (raw, self.genesis.resolve()?) {
(
Expand All @@ -618,7 +639,8 @@ impl<G: RuntimeGenesis, E: serde::Serialize + Clone + 'static> ChainSpec<G, E> {
code,
}),
) => {
let mut storage = RuntimeCaller::new(&code[..]).get_storage_for_config(config)?;
let mut storage =
RuntimeCaller::<HF>::new(&code[..]).get_storage_for_config(config)?;
storage.top.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code);
RawGenesis::from(storage)
},
Expand All @@ -629,7 +651,8 @@ impl<G: RuntimeGenesis, E: serde::Serialize + Clone + 'static> ChainSpec<G, E> {
code,
}),
) => {
let mut storage = RuntimeCaller::new(&code[..]).get_storage_for_patch(patch)?;
let mut storage =
RuntimeCaller::<HF>::new(&code[..]).get_storage_for_patch(patch)?;
storage.top.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code);
RawGenesis::from(storage)
},
Expand Down Expand Up @@ -664,10 +687,11 @@ impl<G: RuntimeGenesis, E: serde::Serialize + Clone + 'static> ChainSpec<G, E> {
}
}

impl<G, E> crate::ChainSpec for ChainSpec<G, E>
impl<G, E, HF> crate::ChainSpec for ChainSpec<G, E, HF>
where
G: RuntimeGenesis + 'static,
E: GetExtension + serde::Serialize + Clone + Send + Sync + 'static,
HF: HostFunctions + Send + Sync,
{
fn boot_nodes(&self) -> &[MultiaddrWithPeerId] {
ChainSpec::boot_nodes(self)
Expand Down
16 changes: 9 additions & 7 deletions substrate/client/chain-spec/src/genesis_config_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
//! A helper module for calling the GenesisBuilder API from arbitrary runtime wasm blobs.

use codec::{Decode, Encode};
pub use sc_executor::sp_wasm_interface::HostFunctions;
use sc_executor::{error::Result, WasmExecutor};
use serde_json::{from_slice, Value};
use sp_core::{
Expand All @@ -30,29 +31,30 @@ use sp_state_machine::BasicExternalities;
use std::borrow::Cow;

/// A utility that facilitates calling the GenesisBuilder API from the runtime wasm code blob.
pub struct GenesisConfigBuilderRuntimeCaller<'a> {
pub struct GenesisConfigBuilderRuntimeCaller<'a, HF = sp_io::SubstrateHostFunctions> {
code: Cow<'a, [u8]>,
code_hash: Vec<u8>,
executor: WasmExecutor<sp_io::SubstrateHostFunctions>,
executor: WasmExecutor<HF>,
}

impl<'a> FetchRuntimeCode for GenesisConfigBuilderRuntimeCaller<'a> {
impl<'a, HF> FetchRuntimeCode for GenesisConfigBuilderRuntimeCaller<'a, HF> {
fn fetch_runtime_code(&self) -> Option<Cow<[u8]>> {
Some(self.code.as_ref().into())
}
}

impl<'a> GenesisConfigBuilderRuntimeCaller<'a> {
impl<'a, HF> GenesisConfigBuilderRuntimeCaller<'a, HF>
where
HF: HostFunctions,
{
/// Creates new instance using the provided code blob.
///
/// This code is later referred to as `runtime`.
pub fn new(code: &'a [u8]) -> Self {
GenesisConfigBuilderRuntimeCaller {
code: code.into(),
code_hash: sp_core::blake2_256(code).to_vec(),
executor: WasmExecutor::<sp_io::SubstrateHostFunctions>::builder()
.with_allow_missing_host_functions(true)
.build(),
executor: WasmExecutor::<HF>::builder().with_allow_missing_host_functions(true).build(),
}
}

Expand Down