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

BlockId removal: refactor: CallExecutor trait #13173

Merged
merged 5 commits into from
Jan 24, 2023
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
13 changes: 8 additions & 5 deletions client/api/src/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! A method call executor interface.

use sc_executor::{RuntimeVersion, RuntimeVersionOf};
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
use sp_runtime::traits::Block as BlockT;
use sp_state_machine::{ExecutionStrategy, OverlayedChanges, StorageProof};
use std::cell::RefCell;

Expand Down Expand Up @@ -54,7 +54,7 @@ pub trait CallExecutor<B: BlockT>: RuntimeVersionOf {
/// No changes are made.
fn call(
&self,
id: &BlockId<B>,
at_hash: <B as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
method: &str,
call_data: &[u8],
strategy: ExecutionStrategy,
Expand All @@ -67,7 +67,7 @@ pub trait CallExecutor<B: BlockT>: RuntimeVersionOf {
/// of the execution context.
fn contextual_call(
&self,
at: &BlockId<B>,
at_hash: <B as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
method: &str,
call_data: &[u8],
changes: &RefCell<OverlayedChanges>,
Expand All @@ -83,14 +83,17 @@ pub trait CallExecutor<B: BlockT>: RuntimeVersionOf {
/// Extract RuntimeVersion of given block
///
/// No changes are made.
fn runtime_version(&self, id: &BlockId<B>) -> Result<RuntimeVersion, sp_blockchain::Error>;
fn runtime_version(
&self,
at_hash: <B as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<RuntimeVersion, sp_blockchain::Error>;

/// Prove the execution of the given `method`.
///
/// No changes are made.
fn prove_execution(
&self,
at: &BlockId<B>,
at_hash: <B as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
method: &str,
call_data: &[u8],
) -> Result<(Vec<u8>, StorageProof), sp_blockchain::Error>;
Expand Down
6 changes: 3 additions & 3 deletions client/finality-grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,18 +464,18 @@ pub trait GenesisAuthoritySetProvider<Block: BlockT> {
fn get(&self) -> Result<AuthorityList, ClientError>;
}

impl<Block: BlockT, E> GenesisAuthoritySetProvider<Block>
for Arc<dyn ExecutorProvider<Block, Executor = E>>
impl<Block: BlockT, E, Client> GenesisAuthoritySetProvider<Block> for Arc<Client>
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
where
E: CallExecutor<Block>,
Client: ExecutorProvider<Block, Executor = E> + HeaderBackend<Block>,
{
fn get(&self) -> Result<AuthorityList, ClientError> {
// This implementation uses the Grandpa runtime API instead of reading directly from the
// `GRANDPA_AUTHORITIES_KEY` as the data may have been migrated since the genesis block of
// the chain, whereas the runtime API is backwards compatible.
self.executor()
.call(
&BlockId::Number(Zero::zero()),
self.expect_block_hash_from_id(&BlockId::Number(Zero::zero()))?,
"GrandpaApi_grandpa_authorities",
&[],
ExecutionStrategy::NativeElseWasm,
Expand Down
2 changes: 1 addition & 1 deletion client/rpc-spec-v2/src/chain_head/chain_head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ where
let res = client
.executor()
.call(
&BlockId::Hash(hash),
hash,
&function,
&call_parameters,
client.execution_extensions().strategies().other,
Expand Down
2 changes: 1 addition & 1 deletion client/rpc/src/state/state_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ where
self.client
.executor()
.call(
&BlockId::Hash(block),
block,
&method,
&call_data,
self.client.execution_extensions().strategies().other,
Expand Down
57 changes: 31 additions & 26 deletions client/service/src/client/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,32 +81,32 @@ where
fn check_override<'a>(
&'a self,
onchain_code: RuntimeCode<'a>,
id: &BlockId<Block>,
hash: <Block as BlockT>::Hash,
) -> sp_blockchain::Result<(RuntimeCode<'a>, RuntimeVersion)>
where
Block: BlockT,
B: backend::Backend<Block>,
{
let on_chain_version = self.on_chain_runtime_version(id)?;
let on_chain_version = self.on_chain_runtime_version(hash)?;
let code_and_version = if let Some(d) = self.wasm_override.as_ref().as_ref().and_then(|o| {
o.get(
&on_chain_version.spec_version,
onchain_code.heap_pages,
&on_chain_version.spec_name,
)
}) {
log::debug!(target: "wasm_overrides", "using WASM override for block {}", id);
log::debug!(target: "wasm_overrides", "using WASM override for block {}", hash);
d
} else if let Some(s) =
self.wasm_substitutes
.get(on_chain_version.spec_version, onchain_code.heap_pages, id)
.get(on_chain_version.spec_version, onchain_code.heap_pages, hash)
{
log::debug!(target: "wasm_substitutes", "Using WASM substitute for block {:?}", id);
log::debug!(target: "wasm_substitutes", "Using WASM substitute for block {:?}", hash);
s
} else {
log::debug!(
target: "wasm_overrides",
"Neither WASM override nor substitute available for block {id}, using onchain code",
"Neither WASM override nor substitute available for block {hash}, using onchain code",
);
(onchain_code, on_chain_version)
};
Expand All @@ -117,12 +117,11 @@ where
/// Returns the on chain runtime version.
fn on_chain_runtime_version(
&self,
id: &BlockId<Block>,
hash: <Block as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
) -> sp_blockchain::Result<RuntimeVersion> {
let mut overlay = OverlayedChanges::default();

let at_hash = self.backend.blockchain().expect_block_hash_from_id(id)?;
let state = self.backend.state_at(at_hash)?;
let state = self.backend.state_at(hash)?;
let mut cache = StorageTransactionCache::<Block, B::State>::default();
let mut ext = Ext::new(&mut overlay, &mut cache, &state, None);
let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);
Expand Down Expand Up @@ -166,21 +165,21 @@ where

fn call(
&self,
at: &BlockId<Block>,
at_hash: <Block as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
method: &str,
call_data: &[u8],
strategy: ExecutionStrategy,
) -> sp_blockchain::Result<Vec<u8>> {
let mut changes = OverlayedChanges::default();
let at_hash = self.backend.blockchain().expect_block_hash_from_id(at)?;
let at_number = self.backend.blockchain().expect_block_number_from_id(at)?;
let at_number =
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(at_hash))?;
let state = self.backend.state_at(at_hash)?;

let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);
let runtime_code =
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;

let runtime_code = self.check_override(runtime_code, at)?.0;
let runtime_code = self.check_override(runtime_code, at_hash)?.0;

let extensions = self.execution_extensions.extensions(
at_hash,
Expand All @@ -206,7 +205,7 @@ where

fn contextual_call(
&self,
at: &BlockId<Block>,
at_hash: <Block as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
method: &str,
call_data: &[u8],
changes: &RefCell<OverlayedChanges>,
Expand All @@ -216,8 +215,8 @@ where
) -> Result<Vec<u8>, sp_blockchain::Error> {
let mut storage_transaction_cache = storage_transaction_cache.map(|c| c.borrow_mut());

let at_hash = self.backend.blockchain().expect_block_hash_from_id(at)?;
let at_number = self.backend.blockchain().expect_block_number_from_id(at)?;
let at_number =
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(at_hash))?;
let state = self.backend.state_at(at_hash)?;

let (execution_manager, extensions) =
Expand All @@ -232,7 +231,7 @@ where

let runtime_code =
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
let runtime_code = self.check_override(runtime_code, at)?.0;
let runtime_code = self.check_override(runtime_code, at_hash)?.0;

match recorder {
Some(recorder) => {
Expand Down Expand Up @@ -275,32 +274,34 @@ where
.map_err(Into::into)
}

fn runtime_version(&self, id: &BlockId<Block>) -> sp_blockchain::Result<RuntimeVersion> {
let at_hash = self.backend.blockchain().expect_block_hash_from_id(id)?;
fn runtime_version(
&self,
at_hash: <Block as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
) -> sp_blockchain::Result<RuntimeVersion> {
let state = self.backend.state_at(at_hash)?;
let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);

let runtime_code =
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
self.check_override(runtime_code, id).map(|(_, v)| v)
self.check_override(runtime_code, at_hash).map(|(_, v)| v)
}

fn prove_execution(
&self,
at: &BlockId<Block>,
at_hash: <Block as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
method: &str,
call_data: &[u8],
) -> sp_blockchain::Result<(Vec<u8>, StorageProof)> {
let at_hash = self.backend.blockchain().expect_block_hash_from_id(at)?;
let at_number = self.backend.blockchain().expect_block_number_from_id(at)?;
let at_number =
self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(at_hash))?;
let state = self.backend.state_at(at_hash)?;

let trie_backend = state.as_trie_backend();

let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(trie_backend);
let runtime_code =
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
let runtime_code = self.check_override(runtime_code, at)?.0;
let runtime_code = self.check_override(runtime_code, at_hash)?.0;

sp_state_machine::prove_execution_on_trie_backend(
trie_backend,
Expand Down Expand Up @@ -340,7 +341,10 @@ where
E: CodeExecutor + RuntimeVersionOf + Clone + 'static,
Block: BlockT,
{
fn runtime_version(&self, at: &BlockId<Block>) -> Result<sp_version::RuntimeVersion, String> {
fn runtime_version(
&self,
at: <Block as BlockT>::Hash,
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<sp_version::RuntimeVersion, String> {
CallExecutor::runtime_version(self, at).map_err(|e| e.to_string())
}
}
Expand All @@ -359,6 +363,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use backend::Backend;
use sc_client_api::in_mem;
use sc_executor::{NativeElseWasmExecutor, WasmExecutionMethod};
use sp_core::{
Expand Down Expand Up @@ -432,7 +437,7 @@ mod tests {
};

let check = call_executor
.check_override(onchain_code, &BlockId::Number(Default::default()))
.check_override(onchain_code, backend.blockchain().info().genesis_hash)
.expect("RuntimeCode override")
.0;

Expand Down
11 changes: 7 additions & 4 deletions client/service/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@ where

/// Get the RuntimeVersion at a given block.
pub fn runtime_version_at(&self, id: &BlockId<Block>) -> sp_blockchain::Result<RuntimeVersion> {
CallExecutor::runtime_version(&self.executor, id)
let hash = self.backend.blockchain().expect_block_hash_from_id(id)?;
CallExecutor::runtime_version(&self.executor, hash)
}

/// Apply a checked and validated block to an operation. If a justification is provided
Expand Down Expand Up @@ -1184,7 +1185,7 @@ where
method: &str,
call_data: &[u8],
) -> sp_blockchain::Result<(Vec<u8>, StorageProof)> {
self.executor.prove_execution(&BlockId::Hash(hash), method, call_data)
self.executor.prove_execution(hash, method, call_data)
}

fn read_proof_collection(
Expand Down Expand Up @@ -1669,9 +1670,10 @@ where
&self,
params: CallApiAtParams<Block, B::State>,
) -> Result<Vec<u8>, sp_api::ApiError> {
let at_hash = self.expect_block_hash_from_id(params.at)?;
self.executor
.contextual_call(
params.at,
at_hash,
params.function,
&params.arguments,
params.overlayed_changes,
Expand All @@ -1683,7 +1685,8 @@ where
}

fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, sp_api::ApiError> {
CallExecutor::runtime_version(&self.executor, at).map_err(Into::into)
let hash = self.backend.blockchain().expect_block_hash_from_id(at)?;
CallExecutor::runtime_version(&self.executor, hash).map_err(Into::into)
}

fn state_at(&self, at: &BlockId<Block>) -> Result<Self::StateBackend, sp_api::ApiError> {
Expand Down
20 changes: 10 additions & 10 deletions client/service/src/client/wasm_substitutes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ use sc_client_api::backend;
use sc_executor::RuntimeVersionOf;
use sp_blockchain::{HeaderBackend, Result};
use sp_core::traits::{FetchRuntimeCode, RuntimeCode, WrappedRuntimeCode};
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, NumberFor},
};
use sp_runtime::traits::{Block as BlockT, NumberFor};
use sp_state_machine::BasicExternalities;
use sp_version::RuntimeVersion;
use std::{
Expand Down Expand Up @@ -54,10 +51,13 @@ impl<Block: BlockT> WasmSubstitute<Block> {
RuntimeCode { code_fetcher: self, hash: self.hash.clone(), heap_pages }
}

/// 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 requested_block_number =
backend.blockchain().block_number_from_id(block_id).ok().flatten();
/// Returns `true` when the substitute matches for the given `hash`.
fn matches(
&self,
hash: <Block as BlockT>::Hash,
backend: &impl backend::Backend<Block>,
) -> bool {
let requested_block_number = backend.blockchain().number(hash).ok().flatten();

Some(self.block_number) <= requested_block_number
}
Expand Down Expand Up @@ -147,10 +147,10 @@ where
&self,
spec: u32,
pages: Option<u64>,
block_id: &BlockId<Block>,
hash: Block::Hash,
) -> Option<(RuntimeCode<'_>, RuntimeVersion)> {
let s = self.substitutes.get(&spec)?;
s.matches(block_id, &*self.backend)
s.matches(hash, &*self.backend)
.then(|| (s.runtime_code(pages), s.version.clone()))
}

Expand Down
6 changes: 3 additions & 3 deletions primitives/version/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub use sp_runtime::{create_runtime_str, StateVersion};
pub use sp_std;

#[cfg(feature = "std")]
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
use sp_runtime::traits::Block as BlockT;

#[cfg(feature = "std")]
pub mod embed;
Expand Down Expand Up @@ -370,14 +370,14 @@ pub trait GetNativeVersion {
#[cfg(feature = "std")]
pub trait GetRuntimeVersionAt<Block: BlockT> {
/// Returns the version of runtime at the given block.
fn runtime_version(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, String>;
fn runtime_version(&self, at: <Block as BlockT>::Hash) -> Result<RuntimeVersion, String>;
}

#[cfg(feature = "std")]
impl<T: GetRuntimeVersionAt<Block>, Block: BlockT> GetRuntimeVersionAt<Block>
for std::sync::Arc<T>
{
fn runtime_version(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, String> {
fn runtime_version(&self, at: <Block as BlockT>::Hash) -> Result<RuntimeVersion, String> {
(&**self).runtime_version(at)
}
}
Expand Down