diff --git a/substrate/client/chain-spec/src/chain_spec.rs b/substrate/client/chain-spec/src/chain_spec.rs index 59d3ac3513..a22a68d294 100644 --- a/substrate/client/chain-spec/src/chain_spec.rs +++ b/substrate/client/chain-spec/src/chain_spec.rs @@ -176,10 +176,10 @@ struct ClientSpec { #[serde(skip_serializing)] #[allow(unused)] genesis: serde::de::IgnoredAny, - /// Mapping from `block_hash` to `wasm_code`. + /// Mapping from `block_number` to `wasm_code`. /// - /// The given `wasm_code` will be used to substitute the on-chain wasm code from the given - /// block hash onwards. + /// The given `wasm_code` will be used to substitute the on-chain wasm code starting with the + /// given block number until the `spec_version` on chain changes. #[serde(default)] code_substitutes: BTreeMap, } diff --git a/substrate/client/service/src/builder.rs b/substrate/client/service/src/builder.rs index c713b4936c..269b7be720 100644 --- a/substrate/client/service/src/builder.rs +++ b/substrate/client/service/src/builder.rs @@ -57,7 +57,7 @@ use sp_core::traits::{CodeExecutor, SpawnNamed}; use sp_keystore::{CryptoStore, SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, BlockIdTo, Zero}, + traits::{Block as BlockT, BlockIdTo, NumberFor, Zero}, BuildStorage, }; use std::{str::FromStr, sync::Arc, time::SystemTime}; @@ -227,7 +227,6 @@ pub fn new_full_client( where TBl: BlockT, TExec: CodeExecutor + RuntimeVersionOf + Clone, - TBl::Hash: FromStr, { new_full_parts(config, telemetry, executor).map(|parts| parts.0) } @@ -241,7 +240,6 @@ pub fn new_full_parts( where TBl: BlockT, TExec: CodeExecutor + RuntimeVersionOf + Clone, - TBl::Hash: FromStr, { let keystore_container = KeystoreContainer::new(&config.keystore)?; @@ -281,14 +279,16 @@ where .chain_spec .code_substitutes() .into_iter() - .map(|(h, c)| { - let hash = TBl::Hash::from_str(&h).map_err(|_| { + .map(|(n, c)| { + let number = NumberFor::::from_str(&n).map_err(|_| { Error::Application(Box::from(format!( - "Failed to parse `{}` as block hash for code substitutes.", - h + "Failed to parse `{}` as block number for code substitutes. \ + In an old version the key for code substitute was a block hash. \ + Please update the chain spec to a version that is compatible with your node.", + n ))) })?; - Ok((hash, c)) + Ok((number, c)) }) .collect::, Error>>()?; diff --git a/substrate/client/service/src/client/client.rs b/substrate/client/service/src/client/client.rs index 9d898c7d1e..8769865978 100644 --- a/substrate/client/service/src/client/client.rs +++ b/substrate/client/service/src/client/client.rs @@ -194,7 +194,7 @@ pub struct ClientConfig { pub no_genesis: bool, /// Map of WASM runtime substitute starting at the child of the given block until the runtime /// version doesn't match anymore. - pub wasm_runtime_substitutes: HashMap>, + pub wasm_runtime_substitutes: HashMap, Vec>, } impl Default for ClientConfig { diff --git a/substrate/client/service/src/client/wasm_substitutes.rs b/substrate/client/service/src/client/wasm_substitutes.rs index 6f9a6dff43..a45eefb7b6 100644 --- a/substrate/client/service/src/client/wasm_substitutes.rs +++ b/substrate/client/service/src/client/wasm_substitutes.rs @@ -18,7 +18,6 @@ //! # WASM substitutes -use parking_lot::RwLock; use sc_client_api::backend; use sc_executor::RuntimeVersionOf; use sp_blockchain::{HeaderBackend, Result}; @@ -40,21 +39,14 @@ use std::{ struct WasmSubstitute { code: Vec, hash: Vec, - /// The hash of the block from that on we should use the substitute. - block_hash: Block::Hash, - /// The block number of `block_hash`. If `None`, the block is still unknown. - block_number: RwLock>>, + /// The block number on which we should start using the substitute. + block_number: NumberFor, } impl WasmSubstitute { - fn new( - code: Vec, - block_hash: Block::Hash, - backend: &impl backend::Backend, - ) -> Result { - let block_number = RwLock::new(backend.blockchain().number(block_hash)?); + fn new(code: Vec, block_number: NumberFor) -> Self { let hash = make_hash(&code); - Ok(Self { code, hash, block_hash, block_number }) + Self { code, hash, block_number } } fn runtime_code(&self, heap_pages: Option) -> RuntimeCode { @@ -63,32 +55,10 @@ impl WasmSubstitute { /// Returns `true` when the substitute matches for the given `block_id`. fn matches(&self, block_id: &BlockId, backend: &impl backend::Backend) -> bool { - let block_number = *self.block_number.read(); - let block_number = if let Some(block_number) = block_number { - block_number - } else { - let block_number = match backend.blockchain().number(self.block_hash) { - Ok(Some(n)) => n, - // still unknown - Ok(None) => return false, - Err(e) => { - log::debug!( - target: "wasm_substitutes", - "Failed to get block number for block hash {:?}: {:?}", - self.block_hash, - e, - ); - return false - }, - }; - *self.block_number.write() = Some(block_number); - block_number - }; - let requested_block_number = backend.blockchain().block_number_from_id(&block_id).ok().flatten(); - Some(block_number) <= requested_block_number + Some(self.block_number) <= requested_block_number } } @@ -145,14 +115,14 @@ where { /// Create a new instance. pub fn new( - substitutes: HashMap>, + substitutes: HashMap, Vec>, executor: Executor, backend: Arc, ) -> Result { let substitutes = substitutes .into_iter() - .map(|(parent_block_hash, code)| { - let substitute = WasmSubstitute::new(code, parent_block_hash, &*backend)?; + .map(|(block_number, code)| { + let substitute = WasmSubstitute::new(code, block_number); let version = Self::runtime_version(&executor, &substitute)?; Ok((version.spec_version, substitute)) })