1#![warn(missing_docs)]
20
21use std::sync::Arc;
22
23use jsonrpsee::RpcModule;
24use polkadot_primitives::{AccountId, Balance, Block, BlockNumber, Hash, Nonce};
25use sc_client_api::AuxStore;
26use sc_consensus_beefy::communication::notification::{
27 BeefyBestBlockStream, BeefyVersionedFinalityProofStream,
28};
29use sc_consensus_grandpa::FinalityProofProvider;
30pub use sc_rpc::SubscriptionTaskExecutor;
31use sc_transaction_pool_api::TransactionPool;
32use sp_api::ProvideRuntimeApi;
33use sp_application_crypto::RuntimeAppPublic;
34use sp_block_builder::BlockBuilder;
35use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
36use sp_consensus::SelectChain;
37use sp_consensus_babe::BabeApi;
38use sp_consensus_beefy::AuthorityIdBound;
39use sp_keystore::KeystorePtr;
40
41pub type RpcExtension = RpcModule<()>;
43
44pub struct BabeDeps {
46 pub babe_worker_handle: sc_consensus_babe::BabeWorkerHandle<Block>,
48 pub keystore: KeystorePtr,
50}
51
52pub struct GrandpaDeps<B> {
54 pub shared_voter_state: sc_consensus_grandpa::SharedVoterState,
56 pub shared_authority_set: sc_consensus_grandpa::SharedAuthoritySet<Hash, BlockNumber>,
58 pub justification_stream: sc_consensus_grandpa::GrandpaJustificationStream<Block>,
60 pub subscription_executor: sc_rpc::SubscriptionTaskExecutor,
62 pub finality_provider: Arc<FinalityProofProvider<B, Block>>,
64}
65
66pub struct BeefyDeps<AuthorityId: AuthorityIdBound> {
68 pub beefy_finality_proof_stream: BeefyVersionedFinalityProofStream<Block, AuthorityId>,
70 pub beefy_best_block_stream: BeefyBestBlockStream<Block>,
72 pub subscription_executor: sc_rpc::SubscriptionTaskExecutor,
74}
75
76pub struct FullDeps<C, P, SC, B, AuthorityId: AuthorityIdBound> {
78 pub client: Arc<C>,
80 pub pool: Arc<P>,
82 pub select_chain: SC,
84 pub chain_spec: Box<dyn sc_chain_spec::ChainSpec>,
86 pub babe: BabeDeps,
88 pub grandpa: GrandpaDeps<B>,
90 pub beefy: BeefyDeps<AuthorityId>,
92 pub backend: Arc<B>,
94}
95
96pub fn create_full<C, P, SC, B, AuthorityId>(
98 FullDeps { client, pool, select_chain, chain_spec, babe, grandpa, beefy, backend }: FullDeps<
99 C,
100 P,
101 SC,
102 B,
103 AuthorityId,
104 >,
105) -> Result<RpcExtension, Box<dyn std::error::Error + Send + Sync>>
106where
107 C: ProvideRuntimeApi<Block>
108 + HeaderBackend<Block>
109 + AuxStore
110 + HeaderMetadata<Block, Error = BlockChainError>
111 + Send
112 + Sync
113 + 'static,
114 C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
115 C::Api: mmr_rpc::MmrRuntimeApi<Block, <Block as sp_runtime::traits::Block>::Hash, BlockNumber>,
116 C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
117 C::Api: BabeApi<Block>,
118 C::Api: BlockBuilder<Block>,
119 P: TransactionPool + Sync + Send + 'static,
120 SC: SelectChain<Block> + 'static,
121 B: sc_client_api::Backend<Block> + Send + Sync + 'static,
122 B::State: sc_client_api::StateBackend<sp_runtime::traits::HashingFor<Block>>,
123 AuthorityId: AuthorityIdBound,
124 <AuthorityId as RuntimeAppPublic>::Signature: Send + Sync,
125{
126 use mmr_rpc::{Mmr, MmrApiServer};
127 use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
128 use sc_consensus_babe_rpc::{Babe, BabeApiServer};
129 use sc_consensus_beefy_rpc::{Beefy, BeefyApiServer};
130 use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer};
131 use sc_sync_state_rpc::{SyncState, SyncStateApiServer};
132 use substrate_frame_rpc_system::{System, SystemApiServer};
133 use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer};
134
135 let mut io = RpcModule::new(());
136 let BabeDeps { babe_worker_handle, keystore } = babe;
137 let GrandpaDeps {
138 shared_voter_state,
139 shared_authority_set,
140 justification_stream,
141 subscription_executor,
142 finality_provider,
143 } = grandpa;
144
145 io.merge(StateMigration::new(client.clone(), backend.clone()).into_rpc())?;
146 io.merge(System::new(client.clone(), pool.clone()).into_rpc())?;
147 io.merge(TransactionPayment::new(client.clone()).into_rpc())?;
148 io.merge(
149 Mmr::new(
150 client.clone(),
151 backend
152 .offchain_storage()
153 .ok_or("Backend doesn't provide the required offchain storage")?,
154 )
155 .into_rpc(),
156 )?;
157 io.merge(
158 Babe::new(client.clone(), babe_worker_handle.clone(), keystore, select_chain).into_rpc(),
159 )?;
160 io.merge(
161 Grandpa::new(
162 subscription_executor,
163 shared_authority_set.clone(),
164 shared_voter_state,
165 justification_stream,
166 finality_provider,
167 )
168 .into_rpc(),
169 )?;
170 io.merge(
171 SyncState::new(chain_spec, client, shared_authority_set, babe_worker_handle)?.into_rpc(),
172 )?;
173
174 io.merge(
175 Beefy::<Block, AuthorityId>::new(
176 beefy.beefy_finality_proof_stream,
177 beefy.beefy_best_block_stream,
178 beefy.subscription_executor,
179 )?
180 .into_rpc(),
181 )?;
182
183 Ok(io)
184}