Repository: paritytech/substrate
File: client/service/src/client/client.rs (Rust)

Code before:
	type StateBackend = B::State;

	fn call_api_at(
		&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(
				at_hash,
				params.function,
				&params.arguments,
				params.overlayed_changes,
				Some(params.storage_transaction_cache),
				params.recorder,
				params.context,
			)
			.map_err(Into::into)
	}

	fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, sp_api::ApiError> {
		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: <Block as BlockT>::Hash) -> Result<Self::StateBackend, sp_api::ApiError> {
		self.state_at(at).map_err(Into::into)
	}
}

/// NOTE: only use this implementation when you are sure there are NO consensus-level BlockImport
/// objects. Otherwise, importing blocks directly into the client would be bypassing
/// important verification work.
#[async_trait::async_trait]
impl<B, E, Block, RA> sc_consensus::BlockImport<Block> for &Client<B, E, Block, RA>
where
	B: backend::Backend<Block>,
	E: CallExecutor<Block> + Send + Sync,
	Block: BlockT,
	Client<B, E, Block, RA>: ProvideRuntimeApi<Block>,
	<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api:
		CoreApi<Block> + ApiExt<Block, StateBackend = B::State>,
	RA: Sync + Send,
	backend::TransactionFor<B, Block>: Send + 'static,
{
	type Error = ConsensusError;
	type Transaction = backend::TransactionFor<B, Block>;

	/// Import a checked and validated block. If a justification is provided in
	/// `BlockImportParams` then `finalized` *must* be true.
	///

Review comment (suggestion):
```suggestion
	fn state_at(&self, at: Block::Hash) -> Result<Self::StateBackend, sp_api::ApiError> {
```

Code after:
	type StateBackend = B::State;

	fn call_api_at(
		&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(
				at_hash,
				params.function,
				&params.arguments,
				params.overlayed_changes,
				Some(params.storage_transaction_cache),
				params.recorder,
				params.context,
			)
			.map_err(Into::into)
	}

	fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, sp_api::ApiError> {
		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: Block::Hash) -> Result<Self::StateBackend, sp_api::ApiError> {
		self.state_at(at).map_err(Into::into)
	}
}

/// NOTE: only use this implementation when you are sure there are NO consensus-level BlockImport
/// objects. Otherwise, importing blocks directly into the client would be bypassing
/// important verification work.
#[async_trait::async_trait]
impl<B, E, Block, RA> sc_consensus::BlockImport<Block> for &Client<B, E, Block, RA>
where
	B: backend::Backend<Block>,
	E: CallExecutor<Block> + Send + Sync,
	Block: BlockT,
	Client<B, E, Block, RA>: ProvideRuntimeApi<Block>,
	<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api:
		CoreApi<Block> + ApiExt<Block, StateBackend = B::State>,
	RA: Sync + Send,
	backend::TransactionFor<B, Block>: Send + 'static,
{
	type Error = ConsensusError;
	type Transaction = backend::TransactionFor<B, Block>;

	/// Import a checked and validated block. If a justification is provided in
	/// `BlockImportParams` then `finalized` *must* be true.
	///