referrerpolicy=no-referrer-when-downgrade

relay_substrate_client/client/
traits.rs

1// Copyright 2019-2021 Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Bridges Common is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17use 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/// Relay uses the `Client` to communicate with the node, connected to Substrate
38/// chain `C`.
39#[async_trait]
40pub trait Client<C: Chain>: 'static + Send + Sync + Clone + Debug {
41	/// Returns error if client has no connected peers or it believes it is far
42	/// behind the chain tip.
43	async fn ensure_synced(&self) -> Result<()>;
44	/// Reconnects the client.
45	async fn reconnect(&self) -> Result<()>;
46
47	/// Return hash of the genesis block.
48	fn genesis_hash(&self) -> HashOf<C>;
49	/// Get header hash by number.
50	async fn header_hash_by_number(&self, number: BlockNumberOf<C>) -> Result<HashOf<C>>;
51	/// Get header by hash.
52	async fn header_by_hash(&self, hash: HashOf<C>) -> Result<HeaderOf<C>>;
53	/// Get header by number.
54	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	/// Get block by hash.
58	async fn block_by_hash(&self, hash: HashOf<C>) -> Result<SignedBlockOf<C>>;
59
60	/// Get best finalized header hash.
61	async fn best_finalized_header_hash(&self) -> Result<HashOf<C>>;
62	/// Get best finalized header number.
63	async fn best_finalized_header_number(&self) -> Result<BlockNumberOf<C>> {
64		Ok(*self.best_finalized_header().await?.number())
65	}
66	/// Get best finalized header.
67	async fn best_finalized_header(&self) -> Result<HeaderOf<C>> {
68		self.header_by_hash(self.best_finalized_header_hash().await?).await
69	}
70
71	/// Get best header.
72	async fn best_header(&self) -> Result<HeaderOf<C>>;
73	/// Get best header hash.
74	async fn best_header_hash(&self) -> Result<HashOf<C>> {
75		Ok(self.best_header().await?.hash())
76	}
77
78	/// Subscribe to new best headers.
79	async fn subscribe_best_headers(&self) -> Result<Subscription<HeaderOf<C>>>;
80	/// Subscribe to new finalized headers.
81	async fn subscribe_finalized_headers(&self) -> Result<Subscription<HeaderOf<C>>>;
82
83	/// Subscribe to GRANDPA finality justifications.
84	async fn subscribe_grandpa_finality_justifications(&self) -> Result<Subscription<Bytes>>
85	where
86		C: ChainWithGrandpa;
87	/// Generates a proof of key ownership for the given authority in the given set.
88	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	/// Subscribe to BEEFY finality justifications.
96	async fn subscribe_beefy_finality_justifications(&self) -> Result<Subscription<Bytes>>;
97
98	/// Return `tokenDecimals` property from the set of chain properties.
99	async fn token_decimals(&self) -> Result<Option<u64>>;
100	/// Get runtime version of the connected chain.
101	async fn runtime_version(&self) -> Result<RuntimeVersion>;
102	/// Get partial runtime version, to use when signing transactions.
103	async fn simple_runtime_version(&self) -> Result<SimpleRuntimeVersion>;
104	/// Returns `true` if version guard can be started.
105	///
106	/// There's no reason to run version guard when version mode is set to `Auto`. It can
107	/// lead to relay shutdown when chain is upgraded, even though we have explicitly
108	/// said that we don't want to shutdown.
109	fn can_start_version_guard(&self) -> bool;
110
111	/// Read raw value from runtime storage.
112	async fn raw_storage_value(
113		&self,
114		at: HashOf<C>,
115		storage_key: StorageKey,
116	) -> Result<Option<StorageData>>;
117	/// Read and decode value from runtime storage.
118	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	/// Read and decode value from runtime storage map.
133	///
134	/// `pallet_prefix` is the name of the pallet (used in `construct_runtime`), which
135	/// "contains" the storage map.
136	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	/// Read and decode value from runtime storage double map.
145	///
146	/// `pallet_prefix` is the name of the pallet (used in `construct_runtime`), which
147	/// "contains" the storage double map.
148	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	/// Returns pending extrinsics from transaction pool.
159	async fn pending_extrinsics(&self) -> Result<Vec<Bytes>>;
160	/// Submit unsigned extrinsic for inclusion in a block.
161	///
162	/// Note: The given transaction needs to be SCALE encoded beforehand.
163	async fn submit_unsigned_extrinsic(&self, transaction: Bytes) -> Result<HashOf<C>>;
164	/// Submit an extrinsic signed by given account.
165	///
166	/// All calls of this method are synchronized, so there can't be more than one active
167	/// `submit_signed_extrinsic()` call. This guarantees that no nonces collision may happen
168	/// if all client instances are clones of the same initial `Client`.
169	///
170	/// Note: The given transaction needs to be SCALE encoded beforehand.
171	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	/// Does exactly the same as `submit_signed_extrinsic`, but keeps watching for extrinsic status
182	/// after submission.
183	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	/// Validate transaction at given block.
194	async fn validate_transaction<SignedTransaction: Encode + Send + 'static>(
195		&self,
196		at: HashOf<C>,
197		transaction: SignedTransaction,
198	) -> Result<TransactionValidity>;
199	/// Returns weight of the given transaction.
200	async fn estimate_extrinsic_weight<SignedTransaction: Encode + Send + 'static>(
201		&self,
202		at: HashOf<C>,
203		transaction: SignedTransaction,
204	) -> Result<Weight>;
205
206	/// Execute runtime call at given block.
207	async fn raw_state_call<Args: Encode + Send>(
208		&self,
209		at: HashOf<C>,
210		method: String,
211		arguments: Args,
212	) -> Result<Bytes>;
213	/// Execute runtime call at given block, provided the input and output types.
214	/// It also performs the input encode and output decode.
215	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	/// Returns storage proof of given storage keys and state root.
229	async fn prove_storage(
230		&self,
231		at: HashOf<C>,
232		keys: Vec<StorageKey>,
233	) -> Result<(StorageProof, HashOf<C>)>;
234}