sp_block_builder/
client_side.rs1use crate::BlockBuilder;
19
20use sp_inherents::{InherentData, InherentDataProvider, InherentIdentifier};
21use sp_runtime::traits::Block as BlockT;
22
23#[derive(Debug)]
25pub enum CheckInherentsError {
26	CreateInherentData(sp_inherents::Error),
28	Client(sp_api::ApiError),
30	CheckInherents(sp_inherents::Error),
32	CheckInherentsUnknownError(InherentIdentifier),
34}
35
36pub async fn check_inherents<Block: BlockT, Client: sp_api::ProvideRuntimeApi<Block>>(
38	client: std::sync::Arc<Client>,
39	at_hash: Block::Hash,
40	block: Block,
41	inherent_data_providers: &impl InherentDataProvider,
42) -> Result<(), CheckInherentsError>
43where
44	Client::Api: BlockBuilder<Block>,
45{
46	let inherent_data = inherent_data_providers
47		.create_inherent_data()
48		.await
49		.map_err(CheckInherentsError::CreateInherentData)?;
50
51	check_inherents_with_data(client, at_hash, block, inherent_data_providers, inherent_data).await
52}
53
54pub async fn check_inherents_with_data<Block: BlockT, Client: sp_api::ProvideRuntimeApi<Block>>(
56	client: std::sync::Arc<Client>,
57	at_hash: Block::Hash,
58	block: Block,
59	inherent_data_provider: &impl InherentDataProvider,
60	inherent_data: InherentData,
61) -> Result<(), CheckInherentsError>
62where
63	Client::Api: BlockBuilder<Block>,
64{
65	let res = client
66		.runtime_api()
67		.check_inherents(at_hash, block, inherent_data)
68		.map_err(CheckInherentsError::Client)?;
69
70	if !res.ok() {
71		for (id, error) in res.into_errors() {
72			match inherent_data_provider.try_handle_error(&id, &error).await {
73				Some(res) => res.map_err(CheckInherentsError::CheckInherents)?,
74				None => return Err(CheckInherentsError::CheckInherentsUnknownError(id)),
75			}
76		}
77	}
78
79	Ok(())
80}