diff --git a/node/src/chain_spec/gdev.rs b/node/src/chain_spec/gdev.rs index b3352cf2ad78b0bfded11585d786df9db17caeb4..b907c0adb575927b1774738acba2be027a38cdd1 100644 --- a/node/src/chain_spec/gdev.rs +++ b/node/src/chain_spec/gdev.rs @@ -30,6 +30,7 @@ use gdev_runtime::{ use sc_service::ChainType; use sp_core::sr25519; use sp_runtime::Perbill; +use std::{env, fs}; pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>; @@ -79,7 +80,8 @@ fn get_parameters(parameters_from_file: &Option<GenesisParameters>) -> CommonPar /// generate development chainspec with Alice validator pub fn gdev_development_chain_spec(json_file_path: String) -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; + let wasm_binary = + get_wasm_binary().ok_or_else(|| "Development wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name "Development", @@ -96,7 +98,7 @@ pub fn gdev_development_chain_spec(json_file_path: String) -> Result<ChainSpec, Some("Alice".to_owned()), ) .expect("Genesis Data must be buildable"); - genesis_data_to_gdev_genesis_conf(genesis_data, wasm_binary) + genesis_data_to_gdev_genesis_conf(genesis_data, &wasm_binary) }, // Bootnodes vec![], @@ -123,7 +125,8 @@ pub fn gdev_development_chain_spec(json_file_path: String) -> Result<ChainSpec, /// generate chainspecs used for benchmarks pub fn benchmark_chain_spec() -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; + let wasm_binary = + get_wasm_binary().ok_or_else(|| "Development wasm not available".to_string())?; // Same as local chain Ok(ChainSpec::from_genesis( // Name @@ -152,7 +155,7 @@ pub fn benchmark_chain_spec() -> Result<ChainSpec, String> { get_parameters, ) .expect("Genesis Data must be buildable"); - genesis_data_to_gdev_genesis_conf(genesis_data, wasm_binary) + genesis_data_to_gdev_genesis_conf(genesis_data, &wasm_binary) }, // Bootnodes vec![], @@ -179,7 +182,7 @@ pub fn benchmark_chain_spec() -> Result<ChainSpec, String> { /// generate live network chainspecs pub fn gen_live_conf(json_file_path: String) -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; + let wasm_binary = get_wasm_binary().ok_or_else(|| "wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name "Ğdev", @@ -194,7 +197,7 @@ pub fn gen_live_conf(json_file_path: String) -> Result<ChainSpec, String> { None, ) .expect("Genesis Data must be buildable"); - genesis_data_to_gdev_genesis_conf(genesis_data, wasm_binary) + genesis_data_to_gdev_genesis_conf(genesis_data, &wasm_binary) }, // Bootnodes vec![], @@ -231,7 +234,7 @@ pub fn local_testnet_config( initial_smiths_len: usize, initial_identities_len: usize, ) -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; + let wasm_binary = get_wasm_binary().ok_or_else(|| "wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name "Ğdev Local Testnet", @@ -259,7 +262,7 @@ pub fn local_testnet_config( get_parameters, ) .expect("Genesis Data must be buildable"); - genesis_data_to_gdev_genesis_conf(genesis_data, wasm_binary) + genesis_data_to_gdev_genesis_conf(genesis_data, &wasm_binary) }, // Bootnodes vec![], @@ -287,7 +290,7 @@ pub fn local_testnet_config( /// custom genesis fn genesis_data_to_gdev_genesis_conf( genesis_data: super::gen_genesis_data::GenesisData<GenesisParameters, SessionKeys>, - wasm_binary: &[u8], + wasm_binary: &Vec<u8>, ) -> gdev_runtime::GenesisConfig { let super::gen_genesis_data::GenesisData { accounts, @@ -430,3 +433,15 @@ fn get_env<T: std::str::FromStr>(env_var_name: &'static str, default_value: T) - .map_or(Ok(default_value), |s| s.parse()) .unwrap_or_else(|_| panic!("{} must be a {}", env_var_name, std::any::type_name::<T>())) } + +/// Get the WASM bytes either from filesytem (`WASM_FILE` env variable giving the path to the wasm blob) +/// or else get the one compiled from source code. +/// Goal: allow to provide the WASM built with srtool, which is reproductible. +fn get_wasm_binary() -> Option<Vec<u8>> { + let wasm_bytes_from_file = if let Ok(file_path) = env::var("WASM_FILE") { + Some(fs::read(file_path).unwrap_or_else(|e| panic!("Could not read wasm file: {}", e))) + } else { + None + }; + wasm_bytes_from_file.or(WASM_BINARY.map(|bytes| bytes.to_vec())) +} diff --git a/node/src/chain_spec/gtest.rs b/node/src/chain_spec/gtest.rs index 5053df57441f728f954abf060a12488fd3003bf7..c454b698cbf68762830a7a5b24307f0604dca81e 100644 --- a/node/src/chain_spec/gtest.rs +++ b/node/src/chain_spec/gtest.rs @@ -38,6 +38,7 @@ use sp_core::{blake2_256, sr25519, Encode, H256}; use sp_finality_grandpa::AuthorityId as GrandpaId; use sp_membership::MembershipData; use std::collections::BTreeMap; +use std::{env, fs}; pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>; pub type AuthorityKeys = ( @@ -149,7 +150,7 @@ pub struct ClientSpec { /// generate development chainspec with Alice validator // there is some code duplication because we can not use ClientSpec pub fn development_chainspecs(json_file_path: String) -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; + let wasm_binary = get_wasm_binary().ok_or_else(|| "wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name "ĞTest Development", @@ -166,7 +167,7 @@ pub fn development_chainspecs(json_file_path: String) -> Result<ChainSpec, Strin Some("Alice".to_owned()), ) .expect("Genesis Data must be buildable"); - genesis_data_to_gtest_genesis_conf(genesis_data, wasm_binary) + genesis_data_to_gtest_genesis_conf(genesis_data, &wasm_binary) }, // Bootnodes vec![], @@ -199,7 +200,7 @@ pub fn live_chainspecs( client_spec: ClientSpec, json_file_path: String, ) -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; + let wasm_binary = get_wasm_binary().ok_or_else(|| "wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name client_spec.name.as_str(), @@ -216,7 +217,7 @@ pub fn live_chainspecs( None, ) .expect("Genesis Data must be buildable"); - genesis_data_to_gtest_genesis_conf(genesis_data, wasm_binary) + genesis_data_to_gtest_genesis_conf(genesis_data, &wasm_binary) }, // Bootnodes client_spec.boot_nodes, @@ -236,7 +237,7 @@ pub fn live_chainspecs( /// custom genesis fn genesis_data_to_gtest_genesis_conf( genesis_data: super::gen_genesis_data::GenesisData<GenesisParameters, SessionKeys>, - wasm_binary: &[u8], + wasm_binary: &Vec<u8>, ) -> gtest_runtime::GenesisConfig { let super::gen_genesis_data::GenesisData { accounts, @@ -341,3 +342,15 @@ fn genesis_data_to_gtest_genesis_conf( treasury: Default::default(), } } + +/// Get the WASM bytes either from filesytem (`WASM_FILE` env variable giving the path to the wasm blob) +/// or else get the one compiled from source code. +/// Goal: allow to provide the WASM built with srtool, which is reproductible. +fn get_wasm_binary() -> Option<Vec<u8>> { + let wasm_bytes_from_file = if let Ok(file_path) = env::var("WASM_FILE") { + Some(fs::read(file_path).unwrap_or_else(|e| panic!("Could not read wasm file: {}", e))) + } else { + None + }; + wasm_bytes_from_file.or(WASM_BINARY.map(|bytes| bytes.to_vec())) +}