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}