relay_substrate_client/client/
traits.rs1use crate::{
18 error::{Error, Result},
19 AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, ChainWithGrandpa, ChainWithTransactions,
20 HashOf, HeaderIdOf, HeaderOf, NonceOf, SignedBlockOf, SimpleRuntimeVersion, Subscription,
21 TransactionTracker, UnsignedTransaction,
22};
23
24use async_trait::async_trait;
25use bp_runtime::{StorageDoubleMapKeyProvider, StorageMapKeyProvider};
26use codec::{Decode, Encode};
27use frame_support::weights::Weight;
28use sp_core::{
29 storage::{StorageData, StorageKey},
30 Bytes, Pair,
31};
32use sp_runtime::{traits::Header as _, transaction_validity::TransactionValidity};
33use sp_trie::StorageProof;
34use sp_version::RuntimeVersion;
35use std::fmt::Debug;
36
37#[async_trait]
40pub trait Client<C: Chain>: 'static + Send + Sync + Clone + Debug {
41 async fn ensure_synced(&self) -> Result<()>;
44 async fn reconnect(&self) -> Result<()>;
46
47 fn genesis_hash(&self) -> HashOf<C>;
49 async fn header_hash_by_number(&self, number: BlockNumberOf<C>) -> Result<HashOf<C>>;
51 async fn header_by_hash(&self, hash: HashOf<C>) -> Result<HeaderOf<C>>;
53 async fn header_by_number(&self, number: BlockNumberOf<C>) -> Result<HeaderOf<C>> {
55 self.header_by_hash(self.header_hash_by_number(number).await?).await
56 }
57 async fn block_by_hash(&self, hash: HashOf<C>) -> Result<SignedBlockOf<C>>;
59
60 async fn best_finalized_header_hash(&self) -> Result<HashOf<C>>;
62 async fn best_finalized_header_number(&self) -> Result<BlockNumberOf<C>> {
64 Ok(*self.best_finalized_header().await?.number())
65 }
66 async fn best_finalized_header(&self) -> Result<HeaderOf<C>> {
68 self.header_by_hash(self.best_finalized_header_hash().await?).await
69 }
70
71 async fn best_header(&self) -> Result<HeaderOf<C>>;
73 async fn best_header_hash(&self) -> Result<HashOf<C>> {
75 Ok(self.best_header().await?.hash())
76 }
77
78 async fn subscribe_best_headers(&self) -> Result<Subscription<HeaderOf<C>>>;
80 async fn subscribe_finalized_headers(&self) -> Result<Subscription<HeaderOf<C>>>;
82
83 async fn subscribe_grandpa_finality_justifications(&self) -> Result<Subscription<Bytes>>
85 where
86 C: ChainWithGrandpa;
87 async fn generate_grandpa_key_ownership_proof(
89 &self,
90 at: HashOf<C>,
91 set_id: sp_consensus_grandpa::SetId,
92 authority_id: sp_consensus_grandpa::AuthorityId,
93 ) -> Result<Option<sp_consensus_grandpa::OpaqueKeyOwnershipProof>>;
94
95 async fn subscribe_beefy_finality_justifications(&self) -> Result<Subscription<Bytes>>;
97
98 async fn token_decimals(&self) -> Result<Option<u64>>;
100 async fn runtime_version(&self) -> Result<RuntimeVersion>;
102 async fn simple_runtime_version(&self) -> Result<SimpleRuntimeVersion>;
104 fn can_start_version_guard(&self) -> bool;
110
111 async fn raw_storage_value(
113 &self,
114 at: HashOf<C>,
115 storage_key: StorageKey,
116 ) -> Result<Option<StorageData>>;
117 async fn storage_value<T: Decode + 'static>(
119 &self,
120 at: HashOf<C>,
121 storage_key: StorageKey,
122 ) -> Result<Option<T>> {
123 self.raw_storage_value(at, storage_key.clone())
124 .await?
125 .map(|encoded_value| {
126 T::decode(&mut &encoded_value.0[..]).map_err(|e| {
127 Error::failed_to_read_storage_value::<C>(at, storage_key, e.into())
128 })
129 })
130 .transpose()
131 }
132 async fn storage_map_value<T: StorageMapKeyProvider>(
137 &self,
138 at: HashOf<C>,
139 pallet_prefix: &str,
140 storage_key: &T::Key,
141 ) -> Result<Option<T::Value>> {
142 self.storage_value(at, T::final_key(pallet_prefix, storage_key)).await
143 }
144 async fn storage_double_map_value<T: StorageDoubleMapKeyProvider>(
149 &self,
150 at: HashOf<C>,
151 pallet_prefix: &str,
152 key1: &T::Key1,
153 key2: &T::Key2,
154 ) -> Result<Option<T::Value>> {
155 self.storage_value(at, T::final_key(pallet_prefix, key1, key2)).await
156 }
157
158 async fn pending_extrinsics(&self) -> Result<Vec<Bytes>>;
160 async fn submit_unsigned_extrinsic(&self, transaction: Bytes) -> Result<HashOf<C>>;
164 async fn submit_signed_extrinsic(
172 &self,
173 signer: &AccountKeyPairOf<C>,
174 prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, NonceOf<C>) -> Result<UnsignedTransaction<C>>
175 + Send
176 + 'static,
177 ) -> Result<HashOf<C>>
178 where
179 C: ChainWithTransactions,
180 AccountIdOf<C>: From<<AccountKeyPairOf<C> as Pair>::Public>;
181 async fn submit_and_watch_signed_extrinsic(
184 &self,
185 signer: &AccountKeyPairOf<C>,
186 prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, NonceOf<C>) -> Result<UnsignedTransaction<C>>
187 + Send
188 + 'static,
189 ) -> Result<TransactionTracker<C, Self>>
190 where
191 C: ChainWithTransactions,
192 AccountIdOf<C>: From<<AccountKeyPairOf<C> as Pair>::Public>;
193 async fn validate_transaction<SignedTransaction: Encode + Send + 'static>(
195 &self,
196 at: HashOf<C>,
197 transaction: SignedTransaction,
198 ) -> Result<TransactionValidity>;
199 async fn estimate_extrinsic_weight<SignedTransaction: Encode + Send + 'static>(
201 &self,
202 at: HashOf<C>,
203 transaction: SignedTransaction,
204 ) -> Result<Weight>;
205
206 async fn raw_state_call<Args: Encode + Send>(
208 &self,
209 at: HashOf<C>,
210 method: String,
211 arguments: Args,
212 ) -> Result<Bytes>;
213 async fn state_call<Args: Encode + Send, Ret: Decode>(
216 &self,
217 at: HashOf<C>,
218 method: String,
219 arguments: Args,
220 ) -> Result<Ret> {
221 let encoded_arguments = arguments.encode();
222 let encoded_output = self.raw_state_call(at, method.clone(), arguments).await?;
223 Ret::decode(&mut &encoded_output.0[..]).map_err(|e| {
224 Error::failed_state_call::<C>(at, method, Bytes(encoded_arguments), e.into())
225 })
226 }
227
228 async fn prove_storage(
230 &self,
231 at: HashOf<C>,
232 keys: Vec<StorageKey>,
233 ) -> Result<(StorageProof, HashOf<C>)>;
234}