relay_substrate_client/
chain.rs1use crate::calls::UtilityCall;
18
19use crate::SimpleRuntimeVersion;
20use bp_header_chain::ChainWithGrandpa as ChainWithGrandpaBase;
21use bp_messages::ChainWithMessages as ChainWithMessagesBase;
22use bp_runtime::{
23 Chain as ChainBase, EncodedOrDecodedCall, HashOf, Parachain as ParachainBase, TransactionEra,
24 TransactionEraOf, UnderlyingChainProvider,
25};
26use codec::{Codec, Decode, Encode, MaxEncodedLen};
27use frame_support::Parameter;
28use jsonrpsee::core::{DeserializeOwned, Serialize};
29use num_traits::Zero;
30use sc_transaction_pool_api::TransactionStatus;
31use scale_info::TypeInfo;
32use sp_core::{storage::StorageKey, Pair};
33use sp_runtime::{
34 generic::SignedBlock,
35 traits::{AtLeast32BitUnsigned, Block as BlockT, Member},
36 ConsensusEngineId, EncodedJustification,
37};
38use std::{fmt::Debug, time::Duration};
39
40pub type SignedBlockOf<C> = <C as Chain>::SignedBlock;
42
43pub trait Chain: ChainBase + Clone {
45 const NAME: &'static str;
47 const BEST_FINALIZED_HEADER_ID_METHOD: &'static str;
53 const FREE_HEADERS_INTERVAL_METHOD: &'static str;
59
60 const AVERAGE_BLOCK_INTERVAL: Duration;
65
66 type SignedBlock: Member + Serialize + DeserializeOwned + BlockWithJustification<Self::Header>;
68 type Call: Clone + Codec + Debug + Send + Sync;
70}
71
72pub trait ChainWithRuntimeVersion: Chain {
76 const RUNTIME_VERSION: Option<SimpleRuntimeVersion>;
80}
81
82pub trait RelayChain: Chain {
86 const PARAS_PALLET_NAME: &'static str;
88 const WITH_CHAIN_BRIDGE_PARACHAINS_PALLET_NAME: &'static str;
91}
92
93pub trait ChainWithGrandpa: Chain + ChainWithGrandpaBase {
99 const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str;
105
106 type KeyOwnerProof: Decode + TypeInfo + Send;
108}
109
110pub trait Parachain: Chain + ParachainBase {}
112
113impl<T> Parachain for T where T: UnderlyingChainProvider + Chain + ParachainBase {}
114
115pub trait ChainWithMessages: Chain + ChainWithMessagesBase {
117 const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str;
120
121 const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str;
124}
125
126pub type CallOf<C> = <C as Chain>::Call;
128pub type TransactionStatusOf<C> = TransactionStatus<HashOf<C>, HashOf<C>>;
130
131pub trait ChainWithBalances: Chain {
134 fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey;
136}
137
138pub trait ChainWithRewards: Chain {
140 const WITH_CHAIN_RELAYERS_PALLET_NAME: Option<&'static str>;
142 type RewardBalance: AtLeast32BitUnsigned + Copy + Member + Parameter + MaxEncodedLen;
144 type Reward: Parameter + MaxEncodedLen + Send + Sync + Copy + Clone;
146
147 fn account_reward_storage_key(
149 account_id: &Self::AccountId,
150 reward: impl Into<Self::Reward>,
151 ) -> StorageKey;
152}
153
154pub type EncodedExtrinsic = Vec<u8>;
156
157pub trait BlockWithJustification<Header> {
159 fn header(&self) -> Header;
161 fn extrinsics(&self) -> Vec<EncodedExtrinsic>;
163 fn justification(&self, engine_id: ConsensusEngineId) -> Option<&EncodedJustification>;
165}
166
167#[derive(Clone, Debug, PartialEq)]
169pub struct UnsignedTransaction<C: Chain> {
170 pub call: EncodedOrDecodedCall<C::Call>,
172 pub nonce: C::Nonce,
174 pub tip: C::Balance,
176 pub era: TransactionEraOf<C>,
178}
179
180impl<C: Chain> UnsignedTransaction<C> {
181 pub fn new(call: EncodedOrDecodedCall<C::Call>, nonce: C::Nonce) -> Self {
183 Self { call, nonce, era: TransactionEra::Immortal, tip: Zero::zero() }
184 }
185
186 pub fn switch_chain<Other>(self) -> UnsignedTransaction<Other>
188 where
189 Other: Chain<
190 Nonce = C::Nonce,
191 Balance = C::Balance,
192 BlockNumber = C::BlockNumber,
193 Hash = C::Hash,
194 >,
195 {
196 UnsignedTransaction {
197 call: EncodedOrDecodedCall::Encoded(self.call.into_encoded()),
198 nonce: self.nonce,
199 tip: self.tip,
200 era: self.era,
201 }
202 }
203
204 #[must_use]
206 pub fn tip(mut self, tip: C::Balance) -> Self {
207 self.tip = tip;
208 self
209 }
210
211 #[must_use]
213 pub fn era(mut self, era: TransactionEraOf<C>) -> Self {
214 self.era = era;
215 self
216 }
217}
218
219pub type AccountKeyPairOf<S> = <S as ChainWithTransactions>::AccountKeyPair;
221
222pub trait ChainWithTransactions: Chain {
224 type AccountKeyPair: Pair + Clone + Send + Sync;
226 type SignedTransaction: Clone + Debug + Encode + Send + 'static;
228
229 fn sign_transaction(
231 param: SignParam<Self>,
232 unsigned: UnsignedTransaction<Self>,
233 ) -> Result<Self::SignedTransaction, crate::Error>
234 where
235 Self: Sized;
236}
237
238pub struct SignParam<C: ChainWithTransactions> {
240 pub spec_version: u32,
242 pub transaction_version: u32,
244 pub genesis_hash: HashOf<C>,
246 pub signer: AccountKeyPairOf<C>,
248}
249
250impl<Block: BlockT> BlockWithJustification<Block::Header> for SignedBlock<Block> {
251 fn header(&self) -> Block::Header {
252 self.block.header().clone()
253 }
254
255 fn extrinsics(&self) -> Vec<EncodedExtrinsic> {
256 self.block.extrinsics().iter().map(Encode::encode).collect()
257 }
258
259 fn justification(&self, engine_id: ConsensusEngineId) -> Option<&EncodedJustification> {
260 self.justifications.as_ref().and_then(|j| j.get(engine_id))
261 }
262}
263
264pub trait UtilityPallet<C: Chain> {
266 fn build_batch_call(calls: Vec<C::Call>) -> C::Call;
268}
269
270pub struct FullRuntimeUtilityPallet<R> {
272 _phantom: std::marker::PhantomData<R>,
273}
274
275impl<C, R> UtilityPallet<C> for FullRuntimeUtilityPallet<R>
276where
277 C: Chain,
278 R: pallet_utility::Config<RuntimeCall = C::Call>,
279 <R as pallet_utility::Config>::RuntimeCall: From<pallet_utility::Call<R>>,
280{
281 fn build_batch_call(calls: Vec<C::Call>) -> C::Call {
282 pallet_utility::Call::batch_all { calls }.into()
283 }
284}
285
286pub struct MockedRuntimeUtilityPallet<Call> {
288 _phantom: std::marker::PhantomData<Call>,
289}
290
291impl<C, Call> UtilityPallet<C> for MockedRuntimeUtilityPallet<Call>
292where
293 C: Chain,
294 C::Call: From<UtilityCall<C::Call>>,
295{
296 fn build_batch_call(calls: Vec<C::Call>) -> C::Call {
297 UtilityCall::batch_all(calls).into()
298 }
299}
300
301pub trait ChainWithUtilityPallet: Chain {
303 type UtilityPallet: UtilityPallet<Self>;
305}