Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

code-substitute: Switch from block_hash to block_number #10600

Merged
merged 5 commits into from
Jan 9, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 3 additions & 3 deletions client/chain-spec/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,10 @@ struct ClientSpec<E> {
#[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<String, Bytes>,
}
Expand Down
16 changes: 8 additions & 8 deletions client/service/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -227,7 +227,6 @@ pub fn new_full_client<TBl, TRtApi, TExec>(
where
TBl: BlockT,
TExec: CodeExecutor + RuntimeVersionOf + Clone,
TBl::Hash: FromStr,
{
new_full_parts(config, telemetry, executor).map(|parts| parts.0)
}
Expand All @@ -241,7 +240,6 @@ pub fn new_full_parts<TBl, TRtApi, TExec>(
where
TBl: BlockT,
TExec: CodeExecutor + RuntimeVersionOf + Clone,
TBl::Hash: FromStr,
{
let keystore_container = KeystoreContainer::new(&config.keystore)?;

Expand Down Expand Up @@ -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::<TBl>::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::<Result<std::collections::HashMap<_, _>, Error>>()?;

Expand Down
2 changes: 1 addition & 1 deletion client/service/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ pub struct ClientConfig<Block: BlockT> {
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<Block::Hash, Vec<u8>>,
pub wasm_runtime_substitutes: HashMap<NumberFor<Block>, Vec<u8>>,
}

impl<Block: BlockT> Default for ClientConfig<Block> {
Expand Down
45 changes: 9 additions & 36 deletions client/service/src/client/wasm_substitutes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

//! # WASM substitutes

use parking_lot::RwLock;
use sc_client_api::backend;
use sc_executor::RuntimeVersionOf;
use sp_blockchain::{HeaderBackend, Result};
Expand All @@ -40,21 +39,17 @@ use std::{
struct WasmSubstitute<Block: BlockT> {
code: Vec<u8>,
hash: Vec<u8>,
/// 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<Option<NumberFor<Block>>>,
/// The block number on which we should start using the substitute.
block_number: NumberFor<Block>,
}

impl<Block: BlockT> WasmSubstitute<Block> {
fn new(
code: Vec<u8>,
block_hash: Block::Hash,
backend: &impl backend::Backend<Block>,
) -> Result<Self> {
let block_number = RwLock::new(backend.blockchain().number(block_hash)?);
block_number: NumberFor<Block>,
) -> 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<u64>) -> RuntimeCode {
Expand All @@ -63,32 +58,10 @@ impl<Block: BlockT> WasmSubstitute<Block> {

/// Returns `true` when the substitute matches for the given `block_id`.
fn matches(&self, block_id: &BlockId<Block>, backend: &impl backend::Backend<Block>) -> 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
}
}

Expand Down Expand Up @@ -145,14 +118,14 @@ where
{
/// Create a new instance.
pub fn new(
substitutes: HashMap<Block::Hash, Vec<u8>>,
substitutes: HashMap<NumberFor<Block>, Vec<u8>>,
executor: Executor,
backend: Arc<Backend>,
) -> Result<Self> {
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))
})
Expand Down