BlockId removal: runtime-api refactor (#13255)

* BlockId removal: refactor of runtime API

It changes the arguments of:
- `ApiExt` methods:  `has_api`, `has_api_with`, `api_version`
- `CallApiAt` method: `runtime_version_at`
from: `BlockId<Block>` to: `Block::Hash`

It also changes the first argument of all generated runtime API calls from: `BlockId<Block>` to: `Block::Hash`

This PR is part of BlockId::Number refactoring analysis (paritytech/substrate#11292)

* BlockId removal: refactor of runtime API - tests

- tests adjusted to new runtime API,
- some tests migrated from block number to block hash

* benchmarking-cli: BlockId(0) migrated to info().genesis_hash

`runtime_api.call()` now requires the block hash instead of BlockId::Number.
To access the genesis hash widely used in benchmarking engine the Client
was constrained to satisfy `sp_blockchain::HeaderBackend<Block>` trait
which provides `info().genesis_hash`.

* trivial: api.call(BlockId) -> api.call(Hash)

- Migrated all `runtime_api.calls` to use Hash
- Noteworthy (?):
-- `validate_transaction_blocking` in transaction pool,

* CallApiAtParams::at changed to Block::Hash

* missed doc updated

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <git@kchr.de>

* ".git/.scripts/commands/fmt/fmt.sh"

* BlockId removal: Benchmark::consumed_weight

Little refactor around `Benchmark::consumed_weight`: `BlockId` removed.

* at_hash renamed

* wrong merge fixed

* beefy worker: merged with master

* beefy: tests: missing block problem fixed

* Apply review suggestion

* fix

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: command-bot <>
This commit is contained in:
Michal Kucharczyk
2023-02-20 23:47:21 +01:00
committed by GitHub
parent ac13aaeb2f
commit 7a10154188
52 changed files with 321 additions and 391 deletions
@@ -316,7 +316,7 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> Result<TokenStream> {
/// Modify the given runtime api declaration to be usable on the client side.
struct ToClientSideDecl<'a> {
block_id: &'a TokenStream,
block_hash: &'a TokenStream,
crate_: &'a TokenStream,
found_attributes: &'a mut HashMap<&'static str, Attribute>,
/// Any error that we found while converting this declaration.
@@ -329,7 +329,7 @@ impl<'a> ToClientSideDecl<'a> {
fn process(mut self, decl: ItemTrait) -> ItemTrait {
let mut decl = self.fold_item_trait(decl);
let block_id = self.block_id;
let block_hash = self.block_hash;
let crate_ = self.crate_;
// Add the special method that will be implemented by the `impl_runtime_apis!` macro
@@ -339,7 +339,7 @@ impl<'a> ToClientSideDecl<'a> {
#[doc(hidden)]
fn __runtime_api_internal_call_api_at(
&self,
at: &#block_id,
at: #block_hash,
context: #crate_::ExecutionContext,
params: std::vec::Vec<u8>,
fn_name: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
@@ -420,7 +420,7 @@ impl<'a> ToClientSideDecl<'a> {
};
let ret_type = return_type_extract_type(&method.sig.output);
fold_fn_decl_for_client_side(&mut method.sig, self.block_id, self.crate_);
fold_fn_decl_for_client_side(&mut method.sig, self.block_hash, self.crate_);
let crate_ = self.crate_;
@@ -621,14 +621,14 @@ fn generate_client_side_decls(decls: &[ItemTrait]) -> Result<TokenStream> {
let decl = decl.clone();
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
let block_id = quote!( #crate_::BlockId<Block> );
let block_hash = quote!( <Block as #crate_::BlockT>::Hash );
let mut found_attributes = HashMap::new();
let mut errors = Vec::new();
let trait_ = decl.ident.clone();
let decl = ToClientSideDecl {
crate_: &crate_,
block_id: &block_id,
block_hash: &block_hash,
found_attributes: &mut found_attributes,
errors: &mut errors,
trait_: &trait_,
@@ -233,7 +233,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
fn has_api<A: #crate_::RuntimeApiInfo + ?Sized>(
&self,
at: &#crate_::BlockId<Block>,
at: <Block as #crate_::BlockT>::Hash,
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
#crate_::CallApiAt::<Block>::runtime_version_at(self.call, at)
.map(|v| #crate_::RuntimeVersion::has_api_with(&v, &A::ID, |v| v == A::VERSION))
@@ -241,7 +241,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
fn has_api_with<A: #crate_::RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
&self,
at: &#crate_::BlockId<Block>,
at: <Block as #crate_::BlockT>::Hash,
pred: P,
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
#crate_::CallApiAt::<Block>::runtime_version_at(self.call, at)
@@ -250,7 +250,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
fn api_version<A: #crate_::RuntimeApiInfo + ?Sized>(
&self,
at: &#crate_::BlockId<Block>,
at: <Block as #crate_::BlockT>::Hash,
) -> std::result::Result<Option<u32>, #crate_::ApiError> where Self: Sized {
#crate_::CallApiAt::<Block>::runtime_version_at(self.call, at)
.map(|v| #crate_::RuntimeVersion::api_version(&v, &A::ID))
@@ -281,8 +281,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
#crate_::StorageChanges<C::StateBackend, Block>,
String
> where Self: Sized {
let at = #crate_::BlockId::Hash(std::clone::Clone::clone(&parent_hash));
let state_version = #crate_::CallApiAt::<Block>::runtime_version_at(self.call, &at)
let state_version = #crate_::CallApiAt::<Block>::runtime_version_at(self.call, std::clone::Clone::clone(&parent_hash))
.map(|v| #crate_::RuntimeVersion::state_version(&v))
.map_err(|e| format!("Failed to get state version: {}", e))?;
@@ -424,7 +423,7 @@ impl<'a> ApiRuntimeImplToApiRuntimeApiImpl<'a> {
input.items.push(parse_quote! {
fn __runtime_api_internal_call_api_at(
&self,
at: &#crate_::BlockId<__SR_API_BLOCK__>,
at: <__SR_API_BLOCK__ as #crate_::BlockT>::Hash,
context: #crate_::ExecutionContext,
params: std::vec::Vec<u8>,
fn_name: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
@@ -38,7 +38,7 @@ const HIDDEN_INCLUDES_ID: &str = "MOCK_IMPL_RUNTIME_APIS";
/// The `advanced` attribute.
///
/// If this attribute is given to a function, the function gets access to the `BlockId` as first
/// If this attribute is given to a function, the function gets access to the `Hash` as first
/// parameter and needs to return a `Result` with the appropriate error type.
const ADVANCED_ATTRIBUTE: &str = "advanced";
@@ -80,14 +80,14 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn has_api<A: #crate_::RuntimeApiInfo + ?Sized>(
&self,
_: &#crate_::BlockId<#block_type>,
_: <Block as #crate_::BlockT>::Hash,
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
Ok(true)
}
fn has_api_with<A: #crate_::RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
&self,
_: &#crate_::BlockId<#block_type>,
_: <Block as #crate_::BlockT>::Hash,
pred: P,
) -> std::result::Result<bool, #crate_::ApiError> where Self: Sized {
Ok(pred(A::VERSION))
@@ -95,7 +95,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn api_version<A: #crate_::RuntimeApiInfo + ?Sized>(
&self,
_: &#crate_::BlockId<#block_type>,
_: <Block as #crate_::BlockT>::Hash,
) -> std::result::Result<Option<u32>, #crate_::ApiError> where Self: Sized {
Ok(Some(A::VERSION))
}
@@ -129,7 +129,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
impl #crate_::Core<#block_type> for #self_ty {
fn __runtime_api_internal_call_api_at(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: #crate_::ExecutionContext,
_: std::vec::Vec<u8>,
_: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
@@ -139,14 +139,14 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn version(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
) -> std::result::Result<#crate_::RuntimeVersion, #crate_::ApiError> {
unimplemented!("`Core::version` not implemented for runtime api mocks")
}
fn version_with_context(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: #crate_::ExecutionContext,
) -> std::result::Result<#crate_::RuntimeVersion, #crate_::ApiError> {
unimplemented!("`Core::version` not implemented for runtime api mocks")
@@ -154,7 +154,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn execute_block(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: #block_type,
) -> std::result::Result<(), #crate_::ApiError> {
unimplemented!("`Core::execute_block` not implemented for runtime api mocks")
@@ -162,7 +162,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn execute_block_with_context(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: #crate_::ExecutionContext,
_: #block_type,
) -> std::result::Result<(), #crate_::ApiError> {
@@ -171,7 +171,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn initialize_block(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: &<#block_type as #crate_::BlockT>::Header,
) -> std::result::Result<(), #crate_::ApiError> {
unimplemented!("`Core::initialize_block` not implemented for runtime api mocks")
@@ -179,7 +179,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<To
fn initialize_block_with_context(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: #crate_::ExecutionContext,
_: &<#block_type as #crate_::BlockT>::Header,
) -> std::result::Result<(), #crate_::ApiError> {
@@ -214,7 +214,7 @@ fn get_at_param_name(
param_names: &mut Vec<Pat>,
param_types_and_borrows: &mut Vec<(TokenStream, bool)>,
function_span: Span,
default_block_id_type: &TokenStream,
default_hash_type: &TokenStream,
) -> Result<(TokenStream, TokenStream)> {
if is_advanced {
if param_names.is_empty() {
@@ -222,7 +222,7 @@ fn get_at_param_name(
function_span,
format!(
"If using the `{}` attribute, it is required that the function \
takes at least one argument, the `BlockId`.",
takes at least one argument, the `Hash`.",
ADVANCED_ATTRIBUTE,
),
))
@@ -232,17 +232,14 @@ fn get_at_param_name(
// `param_types` can not be empty as well.
let ptype_and_borrows = param_types_and_borrows.remove(0);
let span = ptype_and_borrows.1.span();
if !ptype_and_borrows.1 {
return Err(Error::new(
span,
"`BlockId` needs to be taken by reference and not by value!",
))
if ptype_and_borrows.1 {
return Err(Error::new(span, "`Hash` needs to be taken by value and not by reference!"))
}
let name = param_names.remove(0);
Ok((quote!( #name ), ptype_and_borrows.0))
} else {
Ok((quote!(_), default_block_id_type.clone()))
Ok((quote!(_), default_hash_type.clone()))
}
}
@@ -279,7 +276,7 @@ impl<'a> FoldRuntimeApiImpl<'a> {
impl_item.items.push(parse_quote! {
fn __runtime_api_internal_call_api_at(
&self,
_: &#crate_::BlockId<#block_type>,
_: <#block_type as #crate_::BlockT>::Hash,
_: #crate_::ExecutionContext,
_: std::vec::Vec<u8>,
_: &dyn Fn(#crate_::RuntimeVersion) -> &'static str,
@@ -325,19 +322,19 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
};
let block_type = &self.block_type;
let block_id_type = quote!( &#crate_::BlockId<#block_type> );
let hash_type = quote!( <#block_type as #crate_::BlockT>::Hash );
let (at_param_name, block_id_type) = match get_at_param_name(
let (at_param_name, hash_type) = match get_at_param_name(
is_advanced,
&mut param_names,
&mut param_types_and_borrows,
input.span(),
&block_id_type,
&hash_type,
) {
Ok(res) => res,
Err(e) => {
errors.push(e.to_compile_error());
(quote!(_), block_id_type)
(quote!(_), hash_type)
},
};
@@ -345,7 +342,7 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
// Rewrite the input parameters.
input.sig.inputs = parse_quote! {
&self,
#at_param_name: #block_id_type,
#at_param_name: #hash_type,
#( #param_names: #param_types ),*
};
@@ -94,13 +94,13 @@ pub fn replace_wild_card_parameter_names(input: &mut Signature) {
/// Fold the given `Signature` to make it usable on the client side.
pub fn fold_fn_decl_for_client_side(
input: &mut Signature,
block_id: &TokenStream,
block_hash: &TokenStream,
crate_: &TokenStream,
) {
replace_wild_card_parameter_names(input);
// Add `&self, at:& BlockId` as parameters to each function at the beginning.
input.inputs.insert(0, parse_quote!( __runtime_api_at_param__: &#block_id ));
// Add `&self, at:& Block::Hash` as parameters to each function at the beginning.
input.inputs.insert(0, parse_quote!( __runtime_api_at_param__: #block_hash ));
input.inputs.insert(0, parse_quote!(&self));
// Wrap the output in a `Result`
+17 -19
View File
@@ -115,7 +115,7 @@ pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
/// The macro will create two declarations, one for using on the client side and one for using
/// on the runtime side. The declaration for the runtime side is hidden in its own module.
/// The client side declaration gets two extra parameters per function,
/// `&self` and `at: &BlockId<Block>`. The runtime side declaration will match the given trait
/// `&self` and `at: Block::Hash`. The runtime side declaration will match the given trait
/// declaration. Besides one exception, the macro adds an extra generic parameter `Block:
/// BlockT` to the client side and the runtime side. This generic parameter is usable by the
/// user.
@@ -182,7 +182,7 @@ pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
/// ```
///
/// To check if a given runtime implements a runtime api trait, the `RuntimeVersion` has the
/// function `has_api<A>()`. Also the `ApiExt` provides a function `has_api<A>(at: &BlockId)`
/// function `has_api<A>()`. Also the `ApiExt` provides a function `has_api<A>(at: Hash)`
/// to check if the runtime at the given block id implements the requested runtime api trait.
///
/// # Declaring multiple api versions
@@ -400,16 +400,16 @@ pub use sp_api_proc_macro::impl_runtime_apis;
///
/// This attribute can be placed above individual function in the mock implementation to
/// request more control over the function declaration. From the client side each runtime api
/// function is called with the `at` parameter that is a [`BlockId`](sp_api::BlockId). When
/// using the `advanced` attribute, the macro expects that the first parameter of the function
/// is this `at` parameter. Besides that the macro also doesn't do the automatic return value
/// rewrite, which means that full return value must be specified. The full return value is
/// constructed like [`Result`]`<<ReturnValue>, Error>` while `ReturnValue` being the return
/// value that is specified in the trait declaration.
/// function is called with the `at` parameter that is a [`Hash`](sp_runtime::traits::Hash).
/// When using the `advanced` attribute, the macro expects that the first parameter of the
/// function is this `at` parameter. Besides that the macro also doesn't do the automatic
/// return value rewrite, which means that full return value must be specified. The full return
/// value is constructed like [`Result`]`<<ReturnValue>, Error>` while `ReturnValue` being the
/// return value that is specified in the trait declaration.
///
/// ## Example
/// ```rust
/// # use sp_runtime::{traits::Block as BlockT, generic::BlockId};
/// # use sp_runtime::traits::Block as BlockT;
/// # use sp_test_primitives::Block;
/// # use codec;
/// #
@@ -429,16 +429,14 @@ pub use sp_api_proc_macro::impl_runtime_apis;
/// sp_api::mock_impl_runtime_apis! {
/// impl Balance<Block> for MockApi {
/// #[advanced]
/// fn get_balance(&self, at: &BlockId<Block>) -> Result<u64, sp_api::ApiError> {
/// fn get_balance(&self, at: <Block as BlockT>::Hash) -> Result<u64, sp_api::ApiError> {
/// println!("Being called at: {}", at);
///
/// Ok(self.balance.into())
/// }
/// #[advanced]
/// fn set_balance(at: &BlockId<Block>, val: u64) -> Result<(), sp_api::ApiError> {
/// if let BlockId::Number(1) = at {
/// println!("Being called to set balance to: {}", val);
/// }
/// fn set_balance(at: <Block as BlockT>::Hash, val: u64) -> Result<(), sp_api::ApiError> {
/// println!("Being called at: {}", at);
///
/// Ok(().into())
/// }
@@ -539,14 +537,14 @@ pub trait ApiExt<Block: BlockT> {
Self: Sized;
/// Checks if the given api is implemented and versions match.
fn has_api<A: RuntimeApiInfo + ?Sized>(&self, at: &BlockId<Block>) -> Result<bool, ApiError>
fn has_api<A: RuntimeApiInfo + ?Sized>(&self, at_hash: Block::Hash) -> Result<bool, ApiError>
where
Self: Sized;
/// Check if the given api is implemented and the version passes a predicate.
fn has_api_with<A: RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
&self,
at: &BlockId<Block>,
at_hash: Block::Hash,
pred: P,
) -> Result<bool, ApiError>
where
@@ -555,7 +553,7 @@ pub trait ApiExt<Block: BlockT> {
/// Returns the version of the given api.
fn api_version<A: RuntimeApiInfo + ?Sized>(
&self,
at: &BlockId<Block>,
at_hash: Block::Hash,
) -> Result<Option<u32>, ApiError>
where
Self: Sized;
@@ -590,7 +588,7 @@ pub trait ApiExt<Block: BlockT> {
#[cfg(feature = "std")]
pub struct CallApiAtParams<'a, Block: BlockT, Backend: StateBackend<HashFor<Block>>> {
/// The block id that determines the state that should be setup when calling the function.
pub at: &'a BlockId<Block>,
pub at: Block::Hash,
/// The name of the function that should be called.
pub function: &'static str,
/// The encoded arguments of the function.
@@ -619,7 +617,7 @@ pub trait CallApiAt<Block: BlockT> {
) -> Result<Vec<u8>, ApiError>;
/// Returns the runtime version at the given block.
fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, ApiError>;
fn runtime_version_at(&self, at_hash: Block::Hash) -> Result<RuntimeVersion, ApiError>;
/// Get the state `at` the given block.
fn state_at(&self, at: Block::Hash) -> Result<Self::StateBackend, ApiError>;
+12 -13
View File
@@ -17,7 +17,6 @@
use criterion::{criterion_group, criterion_main, Criterion};
use sp_api::ProvideRuntimeApi;
use sp_runtime::generic::BlockId;
use sp_state_machine::ExecutionStrategy;
use substrate_test_runtime_client::{
runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
@@ -27,49 +26,49 @@ fn sp_api_benchmark(c: &mut Criterion) {
c.bench_function("add one with same runtime api", |b| {
let client = substrate_test_runtime_client::new();
let runtime_api = client.runtime_api();
let block_id = BlockId::Hash(client.chain_info().best_hash);
let best_hash = client.chain_info().best_hash;
b.iter(|| runtime_api.benchmark_add_one(&block_id, &1))
b.iter(|| runtime_api.benchmark_add_one(best_hash, &1))
});
c.bench_function("add one with recreating runtime api", |b| {
let client = substrate_test_runtime_client::new();
let block_id = BlockId::Hash(client.chain_info().best_hash);
let best_hash = client.chain_info().best_hash;
b.iter(|| client.runtime_api().benchmark_add_one(&block_id, &1))
b.iter(|| client.runtime_api().benchmark_add_one(best_hash, &1))
});
c.bench_function("vector add one with same runtime api", |b| {
let client = substrate_test_runtime_client::new();
let runtime_api = client.runtime_api();
let block_id = BlockId::Hash(client.chain_info().best_hash);
let best_hash = client.chain_info().best_hash;
let data = vec![0; 1000];
b.iter_with_large_drop(|| runtime_api.benchmark_vector_add_one(&block_id, &data))
b.iter_with_large_drop(|| runtime_api.benchmark_vector_add_one(best_hash, &data))
});
c.bench_function("vector add one with recreating runtime api", |b| {
let client = substrate_test_runtime_client::new();
let block_id = BlockId::Hash(client.chain_info().best_hash);
let best_hash = client.chain_info().best_hash;
let data = vec![0; 1000];
b.iter_with_large_drop(|| client.runtime_api().benchmark_vector_add_one(&block_id, &data))
b.iter_with_large_drop(|| client.runtime_api().benchmark_vector_add_one(best_hash, &data))
});
c.bench_function("calling function by function pointer in wasm", |b| {
let client = TestClientBuilder::new()
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
.build();
let block_id = BlockId::Hash(client.chain_info().best_hash);
b.iter(|| client.runtime_api().benchmark_indirect_call(&block_id).unwrap())
let best_hash = client.chain_info().best_hash;
b.iter(|| client.runtime_api().benchmark_indirect_call(best_hash).unwrap())
});
c.bench_function("calling function in wasm", |b| {
let client = TestClientBuilder::new()
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
.build();
let block_id = BlockId::Hash(client.chain_info().best_hash);
b.iter(|| client.runtime_api().benchmark_direct_call(&block_id).unwrap())
let best_hash = client.chain_info().best_hash;
b.iter(|| client.runtime_api().benchmark_direct_call(best_hash).unwrap())
});
}
@@ -18,11 +18,9 @@
use sp_api::{
decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, ApiError, ApiExt, RuntimeApiInfo,
};
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, GetNodeBlockType},
};
use substrate_test_runtime_client::runtime::Block;
use sp_runtime::traits::{Block as BlockT, GetNodeBlockType};
use substrate_test_runtime_client::runtime::{Block, Hash};
/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
/// trait are done by the `construct_runtime!` macro in a real runtime.
@@ -119,13 +117,13 @@ mock_impl_runtime_apis! {
}
#[advanced]
fn same_name(_: &BlockId<Block>) -> Result<(), ApiError> {
fn same_name(_: <Block as BlockT>::Hash) -> Result<(), ApiError> {
Ok(().into())
}
#[advanced]
fn wild_card(at: &BlockId<Block>, _: u32) -> Result<(), ApiError> {
if let BlockId::Number(1337) = at {
fn wild_card(at: <Block as BlockT>::Hash, _: u32) -> Result<(), ApiError> {
if Hash::repeat_byte(0x0f) == at {
// yeah
Ok(().into())
} else {
@@ -150,19 +148,19 @@ type TestClient = substrate_test_runtime_client::client::Client<
fn test_client_side_function_signature() {
let _test: fn(
&RuntimeApiImpl<Block, TestClient>,
&BlockId<Block>,
<Block as BlockT>::Hash,
u64,
) -> Result<(), ApiError> = RuntimeApiImpl::<Block, TestClient>::test;
let _something_with_block: fn(
&RuntimeApiImpl<Block, TestClient>,
&BlockId<Block>,
<Block as BlockT>::Hash,
Block,
) -> Result<Block, ApiError> = RuntimeApiImpl::<Block, TestClient>::something_with_block;
#[allow(deprecated)]
let _same_name_before_version_2: fn(
&RuntimeApiImpl<Block, TestClient>,
&BlockId<Block>,
<Block as BlockT>::Hash,
) -> Result<String, ApiError> = RuntimeApiImpl::<Block, TestClient>::same_name_before_version_2;
}
@@ -204,8 +202,8 @@ fn check_runtime_api_versions() {
fn mock_runtime_api_has_api() {
let mock = MockApi { block: None };
assert!(mock.has_api::<dyn ApiWithCustomVersion<Block>>(&BlockId::Number(0)).unwrap());
assert!(mock.has_api::<dyn Api<Block>>(&BlockId::Number(0)).unwrap());
assert!(mock.has_api::<dyn ApiWithCustomVersion<Block>>(Hash::default()).unwrap());
assert!(mock.has_api::<dyn Api<Block>>(Hash::default()).unwrap());
}
#[test]
@@ -214,17 +212,17 @@ fn mock_runtime_api_panics_on_calling_old_version() {
let mock = MockApi { block: None };
#[allow(deprecated)]
let _ = mock.same_name_before_version_2(&BlockId::Number(0));
let _ = mock.same_name_before_version_2(Hash::default());
}
#[test]
fn mock_runtime_api_works_with_advanced() {
let mock = MockApi { block: None };
Api::<Block>::same_name(&mock, &BlockId::Number(0)).unwrap();
mock.wild_card(&BlockId::Number(1337), 1).unwrap();
Api::<Block>::same_name(&mock, Hash::default()).unwrap();
mock.wild_card(Hash::repeat_byte(0x0f), 1).unwrap();
assert_eq!(
"Test error".to_string(),
mock.wild_card(&BlockId::Number(1336), 1).unwrap_err().to_string(),
mock.wild_card(Hash::repeat_byte(0x01), 1).unwrap_err().to_string(),
);
}
@@ -36,9 +36,9 @@ use sp_consensus::SelectChain;
fn calling_function_with_strat(strat: ExecutionStrategy) {
let client = TestClientBuilder::new().set_execution_strategy(strat).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
let best_hash = client.chain_info().best_hash;
assert_eq!(runtime_api.benchmark_add_one(&block_id, &1).unwrap(), 2);
assert_eq!(runtime_api.benchmark_add_one(best_hash, &1).unwrap(), 2);
}
#[test]
@@ -57,9 +57,9 @@ fn calling_native_runtime_signature_changed_function() {
.set_execution_strategy(ExecutionStrategy::NativeWhenPossible)
.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
let best_hash = client.chain_info().best_hash;
assert_eq!(runtime_api.function_signature_changed(&block_id).unwrap(), 1);
assert_eq!(runtime_api.function_signature_changed(best_hash).unwrap(), 1);
}
#[test]
@@ -68,10 +68,10 @@ fn calling_wasm_runtime_signature_changed_old_function() {
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
let best_hash = client.chain_info().best_hash;
#[allow(deprecated)]
let res = runtime_api.function_signature_changed_before_version_2(&block_id).unwrap();
let res = runtime_api.function_signature_changed_before_version_2(best_hash).unwrap();
assert_eq!(&res, &[1, 2]);
}
@@ -79,16 +79,16 @@ fn calling_wasm_runtime_signature_changed_old_function() {
fn calling_with_both_strategy_and_fail_on_wasm_should_return_error() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert!(runtime_api.fail_on_wasm(&block_id).is_err());
let best_hash = client.chain_info().best_hash;
assert!(runtime_api.fail_on_wasm(best_hash).is_err());
}
#[test]
fn calling_with_both_strategy_and_fail_on_native_should_work() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert_eq!(runtime_api.fail_on_native(&block_id).unwrap(), 1);
let best_hash = client.chain_info().best_hash;
assert_eq!(runtime_api.fail_on_native(best_hash).unwrap(), 1);
}
#[test]
@@ -97,8 +97,8 @@ fn calling_with_native_else_wasm_and_fail_on_wasm_should_work() {
.set_execution_strategy(ExecutionStrategy::NativeElseWasm)
.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert_eq!(runtime_api.fail_on_wasm(&block_id).unwrap(), 1);
let best_hash = client.chain_info().best_hash;
assert_eq!(runtime_api.fail_on_wasm(best_hash).unwrap(), 1);
}
#[test]
@@ -107,8 +107,8 @@ fn calling_with_native_else_wasm_and_fail_on_native_should_work() {
.set_execution_strategy(ExecutionStrategy::NativeElseWasm)
.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert_eq!(runtime_api.fail_on_native(&block_id).unwrap(), 1);
let best_hash = client.chain_info().best_hash;
assert_eq!(runtime_api.fail_on_native(best_hash).unwrap(), 1);
}
#[test]
@@ -117,18 +117,18 @@ fn use_trie_function() {
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
assert_eq!(runtime_api.use_trie(&block_id).unwrap(), 2);
let best_hash = client.chain_info().best_hash;
assert_eq!(runtime_api.use_trie(best_hash).unwrap(), 2);
}
#[test]
fn initialize_block_works() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
let best_hash = client.chain_info().best_hash;
runtime_api
.initialize_block(
&block_id,
best_hash,
&Header::new(
1,
Default::default(),
@@ -138,7 +138,7 @@ fn initialize_block_works() {
),
)
.unwrap();
assert_eq!(runtime_api.get_block_number(&block_id).unwrap(), 1);
assert_eq!(runtime_api.get_block_number(best_hash).unwrap(), 1);
}
#[test]
@@ -205,10 +205,10 @@ fn call_runtime_api_with_multiple_arguments() {
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
let data = vec![1, 2, 4, 5, 6, 7, 8, 8, 10, 12];
let block_id = BlockId::Number(client.chain_info().best_number);
let best_hash = client.chain_info().best_hash;
client
.runtime_api()
.test_multiple_arguments(&block_id, data.clone(), data.clone(), data.len() as u32)
.test_multiple_arguments(best_hash, data.clone(), data.clone(), data.len() as u32)
.unwrap();
}
@@ -225,8 +225,9 @@ fn disable_logging_works() {
let client = builder.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(0);
runtime_api.do_trace_log(&block_id).expect("Logging should not fail");
runtime_api
.do_trace_log(client.chain_info().genesis_hash)
.expect("Logging should not fail");
log::error!("Logging from native works");
} else {
let executable = std::env::current_exe().unwrap();
@@ -12,7 +12,7 @@ struct MockApi;
sp_api::mock_impl_runtime_apis! {
impl Api<Block> for MockApi {
#[advanced]
fn test(&self, _: BlockId<Block>) -> Result<(), ApiError> {
fn test(&self, _: &Hash) -> Result<(), ApiError> {
Ok(().into())
}
}
@@ -1,10 +1,10 @@
error: `BlockId` needs to be taken by reference and not by value!
--> tests/ui/mock_advanced_block_id_by_value.rs:12:1
error: `Hash` needs to be taken by value and not by reference!
--> tests/ui/mock_advanced_hash_by_reference.rs:12:1
|
12 | / sp_api::mock_impl_runtime_apis! {
13 | | impl Api<Block> for MockApi {
14 | | #[advanced]
15 | | fn test(&self, _: BlockId<Block>) -> Result<(), ApiError> {
15 | | fn test(&self, _: &Hash) -> Result<(), ApiError> {
... |
18 | | }
19 | | }
@@ -1,5 +1,5 @@
error: If using the `advanced` attribute, it is required that the function takes at least one argument, the `BlockId`.
--> tests/ui/mock_advanced_missing_blockid.rs:15:3
error: If using the `advanced` attribute, it is required that the function takes at least one argument, the `Hash`.
--> tests/ui/mock_advanced_missing_hash.rs:15:3
|
15 | fn test(&self) -> Result<(), ApiError> {
| ^^