#![warn(missing_docs)]
pub mod tracing;
use std::{sync::Arc, collections::BTreeMap};
use sc_network::NetworkService;
use jsonrpsee::RpcModule;
use sc_transaction_pool::{ChainApi, Pool};
use sc_transaction_pool_api::TransactionPool;
use sc_client_api::{backend::{Backend, StorageProvider}, client::BlockchainEvents, AuxStore};
use sp_api::ProvideRuntimeApi;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
use fc_rpc::{ EthBlockDataCacheTask, OverrideHandle, };
use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit};
pub use fc_storage::overrides_handle;
use futures::channel::mpsc;
pub use sc_rpc_api::DenyUnsafe;
use core_primitives::{Block, Hash};
use crate::service::RuntimeApiCollection;
pub struct FullDeps<C, P, A: ChainApi, SO, CIDP> {
pub client: Arc<C>,
pub pool: Arc<P>,
pub graph: Arc<Pool<A>>,
pub deny_unsafe: DenyUnsafe,
pub is_authority: bool,
pub network: Arc<NetworkService<Block, Hash>>,
pub sync: Arc<sc_network_sync::SyncingService<Block>>,
pub frontier_backend: Arc<dyn fc_api::Backend<Block> + Send + Sync>,
pub filter_pool: Option<fc_rpc_core::types::FilterPool>,
pub overrides: Arc<OverrideHandle<Block>>,
pub fee_history_cache: FeeHistoryCache,
pub fee_history_cache_limit: FeeHistoryCacheLimit,
pub block_data_cache: Arc<EthBlockDataCacheTask<Block>>,
pub forced_parent_hashes: Option<BTreeMap<sp_core::H256, sp_core::H256>>,
pub pending_create_inherent_data_providers: CIDP,
pub import_justification_tx: mpsc::UnboundedSender<phron_finality::Justification>,
pub justification_translator: phron_finality::JustificationTranslator,
pub sync_oracle: SO,
pub validator_address_cache: Option<phron_finality::ValidatorAddressCache>,
}
pub struct PhronGasAdapter;
impl fc_rpc::EstimateGasAdapter for PhronGasAdapter {
fn adapt_request(mut request: fc_rpc_core::types::CallRequest) -> fc_rpc_core::types::CallRequest {
use sp_core::H160;
const BATCH_PRECOMPILE_ADDRESS: H160 = H160(hex_literal::hex!(
"0000000000000000000000000000000000000808"
));
const BATCH_PRECOMPILE_BATCH_ALL_SELECTOR: [u8; 4] = hex_literal::hex!("96e292b8");
if request.to == Some(BATCH_PRECOMPILE_ADDRESS) {
if let Some(ref mut data) = request.data {
if data.0.len() >= 4 {
data.0[..4].copy_from_slice(&BATCH_PRECOMPILE_BATCH_ALL_SELECTOR);
}
}
}
request
}
}
pub struct DefaultEthConfig<C, BE>(std::marker::PhantomData<( C, BE)>);
impl<C, BE> fc_rpc::EthConfig<Block, C> for DefaultEthConfig<C, BE>
where
C: StorageProvider<Block, BE> + Sync + Send + 'static,
BE: Backend<Block> + 'static,
{
type EstimateGasAdapter = PhronGasAdapter;
type RuntimeStorageOverride =
fc_rpc::frontier_backend_client::SystemAccountId20StorageOverride<Block, C, BE>;
}
pub fn create_full<C, P, BE, A, SO, CIDP, EC>(
deps: FullDeps<C, P, A, SO, CIDP>,
pubsub_notification_sinks: Arc<
fc_mapping_sync::EthereumBlockNotificationSinks<
fc_mapping_sync::EthereumBlockNotification<Block>,
>,
>,
subscription_task_executor: sc_rpc::SubscriptionTaskExecutor,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
BE: Backend<Block> + 'static,
BE::State: sc_client_api::backend::StateBackend<sp_runtime::traits::BlakeTwo256>,
C: BlockchainEvents<Block>
+ ProvideRuntimeApi<Block>
+ StorageProvider<Block, BE>
+ HeaderBackend<Block>
+ HeaderMetadata<Block, Error=BlockChainError>
+ Send + Sync + 'static + AuxStore
+ sc_client_api::UsageProvider<Block>
+ sp_api::CallApiAt<Block>,
C::Api: RuntimeApiCollection,
C::Api: sp_consensus_aura::AuraApi<Block, sp_consensus_aura::sr25519::AuthorityId>,
P: TransactionPool<Block=Block> + 'static + Send + Sync,
A: ChainApi<Block=Block> + 'static,
SO: sp_consensus::SyncOracle + Send + Sync + 'static,
CIDP: sp_inherents::CreateInherentDataProviders<Block, ()> + 'static,
EC: fc_rpc::EthConfig<Block, C>,
{
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use crate::phron_node_rpc::{PhronNode, PhronNodeApiServer};
use substrate_frame_rpc_system::{System, SystemApiServer};
use fc_rpc::{
Eth, EthApiServer, Net, NetApiServer, Web3, Web3ApiServer, TxPool, TxPoolApiServer, EthFilter, EthFilterApiServer,
EthPubSub, EthPubSubApiServer
};
let mut module = RpcModule::new(());
let FullDeps {
client, pool, graph, deny_unsafe, is_authority,
network, sync, frontier_backend, filter_pool,
overrides, fee_history_cache, fee_history_cache_limit, block_data_cache,
forced_parent_hashes, pending_create_inherent_data_providers,
import_justification_tx, justification_translator,
sync_oracle, validator_address_cache,
} = deps;
let signers = Vec::new();
let max_past_logs: u32 = 1024;
module.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?;
module.merge(TransactionPayment::new(client.clone()).into_rpc())?;
module.merge(Net::new(client.clone(), network, true).into_rpc())?;
module.merge(
Eth::<Block, C, P, _, BE, A, CIDP, EC>::new(
client.clone(),
pool.clone(),
graph.clone(),
<Option<fp_rpc::NoTransactionConverter>>::None,
sync.clone(),
signers,
overrides.clone(),
frontier_backend.clone(),
is_authority,
block_data_cache.clone(),
fee_history_cache,
fee_history_cache_limit,
10,
forced_parent_hashes,
pending_create_inherent_data_providers,
Some(Box::new(fc_rpc::pending::AuraConsensusDataProvider::new(
client.clone(),
))),
)
.replace_config::<EC>()
.into_rpc())?;
module.merge(
PhronNode::new(
import_justification_tx,
justification_translator,
client.clone(),
sync_oracle,
validator_address_cache
).into_rpc()
)?;
module.merge(TxPool::new(
client.clone(),
graph.clone()
).into_rpc())?;
module.merge(Web3::new(
client.clone(),
).into_rpc())?;
module.merge(
EthPubSub::new(
pool,
client.clone(),
sync,
subscription_task_executor,
overrides,
pubsub_notification_sinks,
).into_rpc(),
)?;
if let Some(filter_pool) = filter_pool {
module.merge(EthFilter::new(
client,
frontier_backend,
graph,
filter_pool,
500_usize,
max_past_logs,
block_data_cache,
).into_rpc())?;
}
Ok(module)
}