Skip to main content

avail_rust_client/block/
shared.rs

1use avail_rust_core::{AvailHeader, H256, HashNumber, rpc::ExtrinsicInfo, types::HashStringNumber};
2
3use crate::{Client, Error, UserError, chain::Chain, conversions};
4
5/// Fetches the block header for the provided identifier.
6///
7/// # Parameters
8/// - `client`: RPC client used to perform the header query.
9/// - `block_id`: Hash or number identifying the target block.
10///
11/// # Returns
12/// - `Ok(AvailHeader)`: Header returned by the node.
13/// - `Err(Error)`: The RPC call failed or the block could not be resolved.
14///
15/// # Side Effects
16/// - Performs an RPC call through the client's chain interface.
17#[derive(Clone)]
18pub struct BlockContext {
19	/// Client handle used for follow-up RPC calls.
20	pub client: Client,
21	/// Hash or number identifying the target block.
22	pub block_id: HashStringNumber,
23	retry_on_error: Option<bool>,
24}
25
26impl BlockContext {
27	/// Creates a new block context for the provided identifier.
28	///
29	/// # Arguments
30	/// * `client` - Client used to perform subsequent RPC calls.
31	/// * `block_id` - Hash or number identifying the target block.
32	pub fn new(client: Client, block_id: HashStringNumber) -> Self {
33		Self { client, block_id, retry_on_error: None }
34	}
35
36	/// Overrides the retry policy for follow-up RPC calls.
37	///
38	/// # Arguments
39	/// * `value` - `Some(true)` to force retries, `Some(false)` to disable retries, `None` to inherit defaults.
40	pub fn set_retry_on_error(&mut self, value: Option<bool>) {
41		self.retry_on_error = value;
42	}
43
44	/// Reports whether RPC calls should retry after errors.
45	///
46	/// # Returns
47	/// Returns `true` when retries are enabled, otherwise `false`.
48	pub fn should_retry_on_error(&self) -> bool {
49		self.retry_on_error
50			.unwrap_or_else(|| self.client.is_global_retries_enabled())
51	}
52
53	/// Resolves the stored identifier into a [`HashNumber`].
54	///
55	/// # Returns
56	/// Returns the resolved `HashNumber` or an error if conversion fails.
57	pub fn hash_number(&self) -> Result<HashNumber, Error> {
58		conversions::hash_string_number::to_hash_number(self.block_id.clone())
59	}
60
61	/// Returns a chain helper configured with the current retry policy.
62	pub fn chain(&self) -> Chain {
63		self.client.chain().retry_on(self.retry_on_error, None)
64	}
65
66	/// Fetches the block header associated with this context.
67	///
68	/// # Returns
69	/// Returns the header or an error when the block cannot be resolved.
70	pub async fn header(&self) -> Result<AvailHeader, Error> {
71		let header = self.chain().block_header(Some(self.block_id.clone())).await?;
72		let Some(header) = header else {
73			return Err(Error::User(UserError::Other(std::format!(
74				"No block header found for block id: {}",
75				self.block_id
76			))));
77		};
78
79		Ok(header)
80	}
81
82	/// Counts the events emitted by the block referenced by this context.
83	///
84	/// # Returns
85	/// Returns the number of events or an error when the RPC call fails.
86	pub async fn event_count(&self) -> Result<usize, Error> {
87		self.chain().block_event_count(self.block_id.clone()).await
88	}
89}
90
91/// Metadata describing where an extrinsic resides within a block.
92#[derive(Debug, Clone)]
93pub struct BlockExtrinsicMetadata {
94	/// Hash of the extrinsic.
95	pub ext_hash: H256,
96	/// Index of the extrinsic within the block.
97	pub ext_index: u32,
98	/// Pallet identifier associated with the call.
99	pub pallet_id: u8,
100	/// Variant within the pallet identifying the call.
101	pub variant_id: u8,
102	/// Block identifier (hash or number) where the extrinsic resides.
103	pub block_id: HashNumber,
104}
105
106impl BlockExtrinsicMetadata {
107	/// Wraps metadata about an extrinsic inside a block.
108	///
109	/// # Parameters
110	/// - `ext_hash`: Hash of the extrinsic.
111	/// - `ext_index`: Index of the extrinsic within the block.
112	/// - `pallet_id`: Pallet identifier associated with the call.
113	/// - `variant_id`: Variant identifier within the pallet.
114	/// - `block_id`: Hash or number of the block containing the extrinsic.
115	///
116	/// # Returns
117	/// - `Self`: Metadata wrapper encapsulating the supplied values.
118	pub fn new(ext_hash: H256, ext_index: u32, pallet_id: u8, variant_id: u8, block_id: HashNumber) -> Self {
119		Self { ext_hash, ext_index, pallet_id, variant_id, block_id }
120	}
121
122	/// Builds metadata from RPC extrinsic information.
123	///
124	/// # Arguments
125	/// * `info` - RPC result describing an extrinsic.
126	/// * `block_id` - Hash or number identifying the block containing the extrinsic.
127	///
128	/// # Returns
129	/// Returns a metadata wrapper encapsulating the provided information.
130	pub fn from_extrinsic_info(info: &ExtrinsicInfo, block_id: HashNumber) -> Self {
131		Self::new(info.ext_hash, info.ext_index, info.pallet_id, info.variant_id, block_id)
132	}
133}