git.delta.rocks / unique-network / refs/commits / d9a94fdfefd5

difftreelog

refactor merge with new node template

Yaroslav Bolyukin2021-03-31parent: #de5a81f.patch.diff
in: master

6 files changed

modifiednode/src/chain_spec.rsdiffbeforeafterboth
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -3,19 +3,18 @@
 // file 'LICENSE', which is part of this source code package.
 //
 
-// use nft_runtime::{
-//     AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,
-//     SystemConfig, WASM_BINARY,
-// };
-// use nft_runtime::{ContractsConfig, ContractsSchedule, NftConfig, CollectionType};
 use nft_runtime::*;
-use sc_service::ChainType;
+use sp_core::{Pair, Public, sr25519};
+use nft_runtime::{
+	AccountId, AuraConfig, BalancesConfig, EVMConfig, EthereumConfig, GenesisConfig, GrandpaConfig,
+	SudoConfig, SystemConfig, WASM_BINARY, Signature
+};
 use sp_consensus_aura::sr25519::AuthorityId as AuraId;
-use sp_core::{sr25519, Pair, Public};
 use sp_finality_grandpa::AuthorityId as GrandpaId;
-use sp_runtime::traits::{IdentifyAccount, Verify};
+use sp_runtime::traits::{Verify, IdentifyAccount};
+use sc_service::ChainType;
 use serde_json::map::Map;
-// use crate::chain_spec::api::chain_extension::*;
+use std::collections::BTreeMap;
 
 // Note this is the URL for the telemetry server
 //const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
@@ -25,9 +24,9 @@
 
 /// Helper function to generate a crypto pair from seed
 pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
-    TPublic::Pair::from_string(&format!("//{}", seed), None)
-        .expect("static values are valid; qed")
-        .public()
+	TPublic::Pair::from_string(&format!("//{}", seed), None)
+		.expect("static values are valid; qed")
+		.public()
 }
 
 type AccountPublic = <Signature as Verify>::Signer;
@@ -35,14 +34,14 @@
 /// Helper function to generate an account ID from seed
 pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
 where
-    AccountPublic: From<<TPublic::Pair as Pair>::Public>,
+	AccountPublic: From<<TPublic::Pair as Pair>::Public>,
 {
-    AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
+	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
 }
 
 /// Helper function to generate an authority key for Aura
 pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) {
-    (get_from_seed::<AuraId>(s), get_from_seed::<GrandpaId>(s))
+	(get_from_seed::<AuraId>(s), get_from_seed::<GrandpaId>(s))
 }
 
 pub fn development_config() -> Result<ChainSpec, String> {
@@ -138,88 +137,92 @@
 }
 
 fn testnet_genesis(
-    wasm_binary: &[u8],
-    initial_authorities: Vec<(AuraId, GrandpaId)>,
-    root_key: AccountId,
-    endowed_accounts: Vec<AccountId>,
-    enable_println: bool,
+	wasm_binary: &[u8],
+	initial_authorities: Vec<(AuraId, GrandpaId)>,
+	root_key: AccountId,
+	endowed_accounts: Vec<AccountId>,
+	enable_println: bool,
 ) -> GenesisConfig {
 
 	let vested_accounts = vec![
 		get_account_id_from_seed::<sr25519::Public>("Bob"),
 	];
 
-    GenesisConfig {
-        system: Some(SystemConfig {
-            code: wasm_binary.to_vec(),
-            changes_trie_config: Default::default(),
-        }),
-        pallet_balances: Some(BalancesConfig {
-            balances: endowed_accounts
-                .iter()
-                .cloned()
-                .map(|k| (k, 1 << 100))
-                .collect(),
-        }),
-        pallet_aura: Some(AuraConfig {
-            authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),
-        }),
-		pallet_grandpa: Some(GrandpaConfig {
-            authorities: initial_authorities
-                .iter()
-                .map(|x| (x.1.clone(), 1))
-                .collect(),
-		}),
-		pallet_treasury: Some(Default::default()),
-		pallet_sudo: Some(SudoConfig { key: root_key }),
-		pallet_vesting: Some(VestingConfig {
-            vesting: vested_accounts
-                .iter()
-                .cloned()
-                .map(|k| (k, 1000, 100, 1 << 98))
-                .collect(),
-        }),
-        pallet_nft: Some(NftConfig {
-            collection_id: vec![(
-                1,
-                Collection {
-                    owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
-                    mode: CollectionMode::NFT,
-                    access: AccessMode::Normal,
-                    decimal_points: 0,
-                    name: vec![],
-                    description: vec![],
-                    token_prefix: vec![],
-                    mint_mode: false,
+	GenesisConfig {
+		system: SystemConfig {
+			code: wasm_binary.to_vec(),
+			changes_trie_config: Default::default(),
+		},
+		pallet_balances: BalancesConfig {
+			balances: endowed_accounts
+				.iter()
+				.cloned()
+				.map(|k| (k, 1 << 100))
+				.collect(),
+		},
+		pallet_aura: AuraConfig {
+			authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),
+		},
+		pallet_grandpa: GrandpaConfig {
+			authorities: initial_authorities
+				.iter()
+				.map(|x| (x.1.clone(), 1))
+				.collect(),
+		},
+		pallet_treasury: Default::default(),
+		pallet_sudo: SudoConfig { key: root_key },
+		pallet_vesting: VestingConfig {
+			vesting: vested_accounts
+				.iter()
+				.cloned()
+				.map(|k| (k, 1000, 100, 1 << 98))
+				.collect(),
+		},
+		pallet_nft: NftConfig {
+			collection_id: vec![(
+				1,
+				Collection {
+					owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
+					mode: CollectionMode::NFT,
+					access: AccessMode::Normal,
+					decimal_points: 0,
+					name: vec![],
+					description: vec![],
+					token_prefix: vec![],
+					mint_mode: false,
 					offchain_schema: vec![],
 					schema_version: SchemaVersion::default(),
-                    sponsorship: SponsorshipState::Confirmed(get_account_id_from_seed::<sr25519::Public>("Alice")),
-                    const_on_chain_schema: vec![],
+					sponsorship: SponsorshipState::Confirmed(get_account_id_from_seed::<sr25519::Public>("Alice")),
+					const_on_chain_schema: vec![],
 					variable_on_chain_schema: vec![],
 					limits: CollectionLimits::default()
-                },
-            )],
-            nft_item_id: vec![],
-            fungible_item_id: vec![],
-            refungible_item_id: vec![],
-            chain_limit: ChainLimits {
-                collection_numbers_limit: 100000,
-                account_token_ownership_limit: 1000000,
-                collections_admins_limit: 5,
-                custom_data_limit: 2048,
-                nft_sponsor_transfer_timeout: 15,
-                fungible_sponsor_transfer_timeout: 15,
+				},
+			)],
+			nft_item_id: vec![],
+			fungible_item_id: vec![],
+			refungible_item_id: vec![],
+			chain_limit: ChainLimits {
+				collection_numbers_limit: 100000,
+				account_token_ownership_limit: 1000000,
+				collections_admins_limit: 5,
+				custom_data_limit: 2048,
+				nft_sponsor_transfer_timeout: 15,
+				fungible_sponsor_transfer_timeout: 15,
 				refungible_sponsor_transfer_timeout: 15,
 				offchain_schema_limit: 1024,
 				variable_on_chain_schema_limit: 1024,
 				const_on_chain_schema_limit: 1024,
-            },
-        }),
-        pallet_contracts: Some(ContractsConfig {
-            current_schedule: ContractsSchedule {
-                enable_println,
-                ..Default::default()
-            },
-        }),
-    }
+			},
+		},
+		pallet_contracts: ContractsConfig {
+			current_schedule: ContractsSchedule {
+				enable_println,
+				..Default::default()
+			},
+		},
+		pallet_evm: EVMConfig {
+			accounts: BTreeMap::new(),
+		},
+		pallet_ethereum: EthereumConfig {},
+	}
 }
modifiednode/src/command.rsdiffbeforeafterboth
--- a/node/src/command.rs
+++ b/node/src/command.rs
@@ -75,7 +75,7 @@
 			let runner = cli.create_runner(cmd)?;
 			runner.async_run(|config| {
 				let PartialComponents { client, task_manager, import_queue, ..}
-					= service::new_partial(&config)?;
+					= service::new_partial(&config, &cli)?;
 				Ok((cmd.run(client, import_queue), task_manager))
 			})
 		},
@@ -83,7 +83,7 @@
 			let runner = cli.create_runner(cmd)?;
 			runner.async_run(|config| {
 				let PartialComponents { client, task_manager, ..}
-					= service::new_partial(&config)?;
+					= service::new_partial(&config, &cli)?;
 				Ok((cmd.run(client, config.database), task_manager))
 			})
 		},
@@ -91,7 +91,7 @@
 			let runner = cli.create_runner(cmd)?;
 			runner.async_run(|config| {
 				let PartialComponents { client, task_manager, ..}
-					= service::new_partial(&config)?;
+					= service::new_partial(&config, &cli)?;
 				Ok((cmd.run(client, config.chain_spec), task_manager))
 			})
 		},
@@ -99,7 +99,7 @@
 			let runner = cli.create_runner(cmd)?;
 			runner.async_run(|config| {
 				let PartialComponents { client, task_manager, import_queue, ..}
-					= service::new_partial(&config)?;
+					= service::new_partial(&config, &cli)?;
 				Ok((cmd.run(client, import_queue), task_manager))
 			})
 		},
@@ -111,7 +111,7 @@
 			let runner = cli.create_runner(cmd)?;
 			runner.async_run(|config| {
 				let PartialComponents { client, task_manager, backend, ..}
-					= service::new_partial(&config)?;
+					= service::new_partial(&config, &cli)?;
 				Ok((cmd.run(client, backend), task_manager))
 			})
 		},
@@ -130,7 +130,7 @@
 			runner.run_node_until_exit(|config| async move {
 				match config.role {
 					Role::Light => service::new_light(config),
-					_ => service::new_full(config),
+					_ => service::new_full(config, &cli),
 				}.map_err(sc_cli::Error::Service)
 			})
 		}
deletednode/src/lib.rsdiffbeforeafterboth
--- a/node/src/lib.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub mod chain_spec;
-pub mod service;
-pub mod rpc;
modifiednode/src/main.rsdiffbeforeafterboth
--- a/node/src/main.rs
+++ b/node/src/main.rs
@@ -14,5 +14,5 @@
 mod rpc;
 
 fn main() -> sc_cli::Result<()> {
-    command::run()
+	command::run()
 }
modifiednode/src/rpc.rsdiffbeforeafterboth
--- a/node/src/rpc.rs
+++ b/node/src/rpc.rs
@@ -3,17 +3,38 @@
 //! used by Substrate nodes. This file extends those RPC definitions with
 //! capabilities that are specific to this project's runtime configuration.
 
-#![warn(missing_docs)]
-
 use std::sync::Arc;
 
-use nft_runtime::{opaque::Block, AccountId, Balance, Index, BlockNumber};
+use std::collections::BTreeMap;
+use fc_rpc_core::types::{PendingTransactions, FilterPool};
+use nft_runtime::{Hash, AccountId, Index, opaque::Block, Balance};
 use sp_api::ProvideRuntimeApi;
 use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend};
+use sc_client_api::{
+	backend::{StorageProvider, Backend, StateBackend, AuxStore},
+	client::BlockchainEvents
+};
+use sc_rpc::SubscriptionTaskExecutor;
+use sp_runtime::traits::BlakeTwo256;
 use sp_block_builder::BlockBuilder;
-pub use sc_rpc_api::DenyUnsafe;
+use sc_rpc_api::DenyUnsafe;
 use sp_transaction_pool::TransactionPool;
-use pallet_contracts_rpc::{Contracts, ContractsApi};
+use sc_network::NetworkService;
+use jsonrpc_pubsub::manager::SubscriptionManager;
+use pallet_ethereum::EthereumStorageSchema;
+use fc_rpc::{StorageOverride, SchemaV1Override};
+
+/// Light client extra dependencies.
+pub struct LightDeps<C, F, P> {
+	/// The client instance to use.
+	pub client: Arc<C>,
+	/// Transaction pool instance.
+	pub pool: Arc<P>,
+	/// Remote access to the blockchain (async).
+	pub remote_blockchain: Arc<dyn sc_client_api::light::RemoteBlockchain<Block>>,
+	/// Fetcher instance.
+	pub fetcher: Arc<F>,
+}
 
 /// Full client dependencies.
 pub struct FullDeps<C, P> {
@@ -23,47 +44,155 @@
 	pub pool: Arc<P>,
 	/// Whether to deny unsafe calls
 	pub deny_unsafe: DenyUnsafe,
+	/// The Node authority flag
+	pub is_authority: bool,
+	/// Whether to enable dev signer
+	pub enable_dev_signer: bool,
+	/// Network service
+	pub network: Arc<NetworkService<Block, Hash>>,
+	/// Ethereum pending transactions.
+	pub pending_transactions: PendingTransactions,
+	/// EthFilterApi pool.
+	pub filter_pool: Option<FilterPool>,
+	/// Backend.
+	pub backend: Arc<fc_db::Backend<Block>>,
 }
 
 /// Instantiate all full RPC extensions.
-pub fn create_full<C, P>(
+pub fn create_full<C, P, BE>(
 	deps: FullDeps<C, P>,
+	subscription_task_executor: SubscriptionTaskExecutor
 ) -> jsonrpc_core::IoHandler<sc_rpc::Metadata> where
-	C: ProvideRuntimeApi<Block>,
-	C: HeaderBackend<Block> + HeaderMetadata<Block, Error=BlockChainError> + 'static,
+	BE: Backend<Block> + 'static,
+	BE::State: StateBackend<BlakeTwo256>,
+	C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,
+	C: BlockchainEvents<Block>,
+	C: HeaderBackend<Block> + HeaderMetadata<Block, Error=BlockChainError>,
 	C: Send + Sync + 'static,
 	C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
-	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
 	C::Api: BlockBuilder<Block>,
-	C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber>,
-	P: TransactionPool + 'static,
+	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
+	C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
+	P: TransactionPool<Block=Block> + 'static,
 {
 	use substrate_frame_rpc_system::{FullSystem, SystemApi};
 	use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
+	use fc_rpc::{
+		EthApi, EthApiServer, EthFilterApi, EthFilterApiServer, NetApi, NetApiServer,
+		EthPubSubApi, EthPubSubApiServer, Web3Api, Web3ApiServer, EthDevSigner, EthSigner,
+		HexEncodedIdProvider,
+	};
 
 	let mut io = jsonrpc_core::IoHandler::default();
 	let FullDeps {
 		client,
 		pool,
 		deny_unsafe,
+		is_authority,
+		network,
+		pending_transactions,
+		filter_pool,
+		backend,
+		enable_dev_signer,
 	} = deps;
 
 	io.extend_with(
-		SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe))
+		SystemApi::to_delegate(FullSystem::new(client.clone(), pool.clone(), deny_unsafe))
 	);
 
 	io.extend_with(
 		TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone()))
 	);
 
-    io.extend_with(
-        ContractsApi::to_delegate(Contracts::new(client.clone()))
+	// io.extend_with(
+	// 	ContractsApi::to_delegate(Contracts::new(client.clone()))
+	// );
+
+	let mut signers = Vec::new();
+	if enable_dev_signer {
+		signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
+	}
+	let mut overrides = BTreeMap::new();
+	overrides.insert(
+		EthereumStorageSchema::V1,
+		Box::new(SchemaV1Override::new(client.clone())) as Box<dyn StorageOverride<_> + Send + Sync>
+	);
+	io.extend_with(
+		EthApiServer::to_delegate(EthApi::new(
+			client.clone(),
+			pool.clone(),
+			nft_runtime::TransactionConverter,
+			network.clone(),
+			pending_transactions.clone(),
+			signers,
+			overrides,
+			backend,
+			is_authority,
+		))
+	);
+
+	if let Some(filter_pool) = filter_pool {
+		io.extend_with(
+			EthFilterApiServer::to_delegate(EthFilterApi::new(
+				client.clone(),
+				filter_pool.clone(),
+				500 as usize, // max stored filters
+			))
+		);
+	}
+
+	io.extend_with(
+		NetApiServer::to_delegate(NetApi::new(
+			client.clone(),
+			network.clone(),
+		))
 	);
-		
-	// Extend this RPC with a custom API by using the following syntax.
-	// `YourRpcStruct` should have a reference to a client, which is needed
-	// to call into the runtime.
-	// `io.extend_with(YourRpcTrait::to_delegate(YourRpcStruct::new(ReferenceToClient, ...)));`
 
+	io.extend_with(
+		Web3ApiServer::to_delegate(Web3Api::new(
+			client.clone(),
+		))
+	);
+
+	io.extend_with(
+		EthPubSubApiServer::to_delegate(EthPubSubApi::new(
+			pool.clone(),
+			client.clone(),
+			network.clone(),
+			SubscriptionManager::<HexEncodedIdProvider>::with_id_provider(
+				HexEncodedIdProvider::default(),
+				Arc::new(subscription_task_executor)
+			),
+		))
+	);
+
+	io
+}
+
+/// Instantiate all Light RPC extensions.
+pub fn create_light<C, P, M, F>(
+	deps: LightDeps<C, F, P>,
+) -> jsonrpc_core::IoHandler<M> where
+	C: sp_blockchain::HeaderBackend<Block>,
+	C: Send + Sync + 'static,
+	F: sc_client_api::light::Fetcher<Block> + 'static,
+	P: TransactionPool + 'static,
+	M: jsonrpc_core::Metadata + Default,
+{
+	use substrate_frame_rpc_system::{LightSystem, SystemApi};
+
+	let LightDeps {
+		client,
+		pool,
+		remote_blockchain,
+		fetcher
+	} = deps;
+	let mut io = jsonrpc_core::IoHandler::default();
+	io.extend_with(
+		SystemApi::<Hash, AccountId, Index>::to_delegate(
+			LightSystem::new(client, remote_blockchain, fetcher, pool)
+		)
+	);
+
 	io
 }
modifiednode/src/service.rsdiffbeforeafterboth
before · node/src/service.rs
1//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.23//4// This file is subject to the terms and conditions defined in5// file 'LICENSE', which is part of this source code package.6//78use std::sync::Arc;9use std::time::Duration;10use sc_client_api::{ExecutorProvider, RemoteBackend};11use nft_runtime::{self, opaque::Block, RuntimeApi};12use sc_service::{error::Error as ServiceError, Configuration, TaskManager};13use sp_inherents::InherentDataProviders;14use sc_executor::native_executor_instance;15pub use sc_executor::NativeExecutor;16use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};17use sc_finality_grandpa::SharedVoterState;18use sc_keystore::LocalKeystore;1920// Our native executor instance.21native_executor_instance!(22	pub Executor,23	nft_runtime::api::dispatch,24	nft_runtime::native_version,25	frame_benchmarking::benchmarking::HostFunctions,26);2728type FullClient = sc_service::TFullClient<Block, RuntimeApi, Executor>;29type FullBackend = sc_service::TFullBackend<Block>;30type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;3132pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponents<33	FullClient, FullBackend, FullSelectChain,34	sp_consensus::DefaultImportQueue<Block, FullClient>,35	sc_transaction_pool::FullPool<Block, FullClient>,36	(37		sc_consensus_aura::AuraBlockImport<38			Block,39			FullClient,40			sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,41			AuraPair42		>,43		sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>,44	)45>, ServiceError> {46	if config.keystore_remote.is_some() {47		return Err(ServiceError::Other(48			format!("Remote Keystores are not supported.")))49	}50	let inherent_data_providers = sp_inherents::InherentDataProviders::new();5152	let (client, backend, keystore_container, task_manager) =53		sc_service::new_full_parts::<Block, RuntimeApi, Executor>(&config)?;54	let client = Arc::new(client);5556	let select_chain = sc_consensus::LongestChain::new(backend.clone());5758	let transaction_pool = sc_transaction_pool::BasicPool::new_full(59		config.transaction_pool.clone(),60		config.role.is_authority().into(),61		config.prometheus_registry(),62		task_manager.spawn_handle(),63		client.clone(),64	);6566	let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import(67		client.clone(), &(client.clone() as Arc<_>), select_chain.clone(),68	)?;6970	let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(71		grandpa_block_import.clone(), client.clone(),72	);7374	let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>(75		sc_consensus_aura::slot_duration(&*client)?,76		aura_block_import.clone(),77		Some(Box::new(grandpa_block_import.clone())),78		client.clone(),79		inherent_data_providers.clone(),80		&task_manager.spawn_handle(),81		config.prometheus_registry(),82		sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),83	)?;8485	Ok(sc_service::PartialComponents {86		client, backend, task_manager, import_queue, keystore_container, select_chain, transaction_pool,87		inherent_data_providers,88		other: (aura_block_import, grandpa_link),89	})90}9192fn remote_keystore(_url: &String) -> Result<Arc<LocalKeystore>, &'static str> {93	// FIXME: here would the concrete keystore be built,94	//        must return a concrete type (NOT `LocalKeystore`) that95	//        implements `CryptoStore` and `SyncCryptoStore`96	Err("Remote Keystore not supported.")97}9899/// Builds a new service for a full client.100pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError> {101	let sc_service::PartialComponents {102		client, backend, mut task_manager, import_queue, mut keystore_container, select_chain, transaction_pool,103		inherent_data_providers,104		other: (block_import, grandpa_link),105	} = new_partial(&config)?;106107	if let Some(url) = &config.keystore_remote {108		match remote_keystore(url) {109			Ok(k) => keystore_container.set_remote_keystore(k),110			Err(e) => {111				return Err(ServiceError::Other(112					format!("Error hooking up remote keystore for {}: {}", url, e)))113			}114		};115	}116117	config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());118119	let (network, network_status_sinks, system_rpc_tx, network_starter) =120		sc_service::build_network(sc_service::BuildNetworkParams {121			config: &config,122			client: client.clone(),123			transaction_pool: transaction_pool.clone(),124			spawn_handle: task_manager.spawn_handle(),125			import_queue,126			on_demand: None,127			block_announce_validator_builder: None,128		})?;129130	if config.offchain_worker.enabled {131		sc_service::build_offchain_workers(132			&config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(),133		);134	}135136	let role = config.role.clone();137	let force_authoring = config.force_authoring;138	let backoff_authoring_blocks: Option<()> = None;139	let name = config.network.node_name.clone();140	let enable_grandpa = !config.disable_grandpa;141	let prometheus_registry = config.prometheus_registry().cloned();142143	let rpc_extensions_builder = {144		let client = client.clone();145		let pool = transaction_pool.clone();146147		Box::new(move |deny_unsafe, _| {148			let deps = crate::rpc::FullDeps {149				client: client.clone(),150				pool: pool.clone(),151				deny_unsafe,152			};153154			crate::rpc::create_full(deps)155		})156	};157158	let (_rpc_handlers, telemetry_connection_notifier) = sc_service::spawn_tasks(159		sc_service::SpawnTasksParams {160			network: network.clone(),161			client: client.clone(),162			keystore: keystore_container.sync_keystore(),163			task_manager: &mut task_manager,164			transaction_pool: transaction_pool.clone(),165			rpc_extensions_builder,166			on_demand: None,167			remote_blockchain: None,168			backend,169			network_status_sinks,170			system_rpc_tx,171			config,172		},173	)?;174175	if role.is_authority() {176		let proposer = sc_basic_authorship::ProposerFactory::new(177			task_manager.spawn_handle(),178			client.clone(),179			transaction_pool,180			prometheus_registry.as_ref(),181		);182183		let can_author_with =184			sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());185186		let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _, _>(187			sc_consensus_aura::slot_duration(&*client)?,188			client.clone(),189			select_chain,190			block_import,191			proposer,192			network.clone(),193			inherent_data_providers.clone(),194			force_authoring,195			backoff_authoring_blocks,196			keystore_container.sync_keystore(),197			can_author_with,198		)?;199200		// the AURA authoring task is considered essential, i.e. if it201		// fails we take down the service with it.202		task_manager.spawn_essential_handle().spawn_blocking("aura", aura);203	}204205	// if the node isn't actively participating in consensus then it doesn't206	// need a keystore, regardless of which protocol we use below.207	let keystore = if role.is_authority() {208		Some(keystore_container.sync_keystore())209	} else {210		None211	};212213	let grandpa_config = sc_finality_grandpa::Config {214		// FIXME #1578 make this available through chainspec215		gossip_duration: Duration::from_millis(333),216		justification_period: 512,217		name: Some(name),218		observer_enabled: false,219		keystore,220		is_authority: role.is_network_authority(),221	};222223	if enable_grandpa {224		// start the full GRANDPA voter225		// NOTE: non-authorities could run the GRANDPA observer protocol, but at226		// this point the full voter should provide better guarantees of block227		// and vote data availability than the observer. The observer has not228		// been tested extensively yet and having most nodes in a network run it229		// could lead to finality stalls.230		let grandpa_config = sc_finality_grandpa::GrandpaParams {231			config: grandpa_config,232			link: grandpa_link,233			network,234			telemetry_on_connect: telemetry_connection_notifier.map(|x| x.on_connect_stream()),235			voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),236			prometheus_registry,237			shared_voter_state: SharedVoterState::empty(),238		};239240		// the GRANDPA voter task is considered infallible, i.e.241		// if it fails we take down the service with it.242		task_manager.spawn_essential_handle().spawn_blocking(243			"grandpa-voter",244			sc_finality_grandpa::run_grandpa_voter(grandpa_config)?245		);246	}247248	network_starter.start_network();249	Ok(task_manager)250}251/// Builds a new service for a light client.252pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError> {253	let (client, backend, keystore_container, mut task_manager, on_demand) =254		sc_service::new_light_parts::<Block, RuntimeApi, Executor>(&config)?;255256	config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());257258	let select_chain = sc_consensus::LongestChain::new(backend.clone());259260	let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(261		config.transaction_pool.clone(),262		config.prometheus_registry(),263		task_manager.spawn_handle(),264		client.clone(),265		on_demand.clone(),266	));267268	let (grandpa_block_import, _) = sc_finality_grandpa::block_import(269		client.clone(),270		&(client.clone() as Arc<_>),271		select_chain.clone(),272	)?;273274	let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(275		grandpa_block_import.clone(),276		client.clone(),277	);278279	let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>(280		sc_consensus_aura::slot_duration(&*client)?,281		aura_block_import,282		Some(Box::new(grandpa_block_import)),283		client.clone(),284		InherentDataProviders::new(),285		&task_manager.spawn_handle(),286		config.prometheus_registry(),287		sp_consensus::NeverCanAuthor,288	)?;289290	let (network, network_status_sinks, system_rpc_tx, network_starter) =291		sc_service::build_network(sc_service::BuildNetworkParams {292			config: &config,293			client: client.clone(),294			transaction_pool: transaction_pool.clone(),295			spawn_handle: task_manager.spawn_handle(),296			import_queue,297			on_demand: Some(on_demand.clone()),298			block_announce_validator_builder: None,299		})?;300301	if config.offchain_worker.enabled {302		sc_service::build_offchain_workers(303			&config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(),304		);305	}306307	sc_service::spawn_tasks(sc_service::SpawnTasksParams {308		remote_blockchain: Some(backend.remote_blockchain()),309		transaction_pool,310		task_manager: &mut task_manager,311		on_demand: Some(on_demand),312		rpc_extensions_builder: Box::new(|_, _| ()),313		config,314		client,315		keystore: keystore_container.sync_keystore(),316		backend,317		network,318		network_status_sinks,319		system_rpc_tx,320	})?;321322	network_starter.start_network();323324	Ok(task_manager)325}
after · node/src/service.rs
1//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.23//4// This file is subject to the terms and conditions defined in5// file 'LICENSE', which is part of this source code package.6//78use std::{sync::{Arc, Mutex}, cell::RefCell, time::Duration, collections::{HashMap, BTreeMap}};9use fc_rpc::EthTask;10use fc_rpc_core::types::{FilterPool, PendingTransactions};11use sc_client_api::{ExecutorProvider, RemoteBackend, BlockchainEvents};12use fc_consensus::FrontierBlockImport;13use fc_mapping_sync::MappingSyncWorker;14use nft_runtime::{self, opaque::Block, RuntimeApi, SLOT_DURATION};15use sc_service::{error::Error as ServiceError, Configuration, TaskManager, BasePath};16use sp_inherents::{InherentDataProviders, ProvideInherentData, InherentIdentifier, InherentData};17use sc_executor::native_executor_instance;18pub use sc_executor::NativeExecutor;19use sc_consensus_aura::{ImportQueueParams, StartAuraParams, SlotProportion};20use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};21use sc_finality_grandpa::SharedVoterState;22use sp_timestamp::InherentError;23use sc_telemetry::{Telemetry, TelemetryWorker};24use sc_cli::SubstrateCli;25use futures::StreamExt;2627use crate::cli::Cli;2829// Our native executor instance.30native_executor_instance!(31	pub Executor,32	nft_runtime::api::dispatch,33	nft_runtime::native_version,34	frame_benchmarking::benchmarking::HostFunctions,35);3637type FullClient = sc_service::TFullClient<Block, RuntimeApi, Executor>;38type FullBackend = sc_service::TFullBackend<Block>;39type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;4041pub type ConsensusResult = (42	sc_consensus_aura::AuraBlockImport<43		Block,44		FullClient,45		FrontierBlockImport<46			Block,47			sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,48			FullClient49		>,50		AuraPair51	>,52	sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>53);5455/// Provide a mock duration starting at 0 in millisecond for timestamp inherent.56/// Each call will increment timestamp by slot_duration making Aura think time has passed.57pub struct MockTimestampInherentDataProvider;5859pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0";6061thread_local!(static TIMESTAMP: RefCell<u64> = RefCell::new(0));6263impl ProvideInherentData for MockTimestampInherentDataProvider {64	fn inherent_identifier(&self) -> &'static InherentIdentifier {65		&INHERENT_IDENTIFIER66	}6768	fn provide_inherent_data(69		&self,70		inherent_data: &mut InherentData,71	) -> Result<(), sp_inherents::Error> {72		TIMESTAMP.with(|x| {73			*x.borrow_mut() += SLOT_DURATION;74			inherent_data.put_data(INHERENT_IDENTIFIER, &*x.borrow())75		})76	}7778	fn error_to_string(&self, error: &[u8]) -> Option<String> {79		InherentError::try_from(&INHERENT_IDENTIFIER, error).map(|e| format!("{:?}", e))80	}81}8283pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {84	let config_dir = config.base_path.as_ref()85		.map(|base_path| base_path.config_dir(config.chain_spec.id()))86		.unwrap_or_else(|| {87			BasePath::from_project("", "", &crate::cli::Cli::executable_name())88				.config_dir(config.chain_spec.id())89		});90	let database_dir = config_dir.join("frontier").join("db");9192	Ok(Arc::new(fc_db::Backend::<Block>::new(&fc_db::DatabaseSettings {93		source: fc_db::DatabaseSettingsSrc::RocksDb {94			path: database_dir,95			cache_size: 0,96		}97	})?))98}99100pub fn new_partial(config: &Configuration, #[allow(unused_variables)] cli: &Cli) -> Result<101	sc_service::PartialComponents<102		FullClient, FullBackend, FullSelectChain,103		sp_consensus::import_queue::BasicQueue<Block, sp_api::TransactionFor<FullClient, Block>>,104		sc_transaction_pool::FullPool<Block, FullClient>,105		(ConsensusResult, PendingTransactions, Option<FilterPool>, Arc<fc_db::Backend<Block>>, Option<Telemetry>),106>, ServiceError> {107	let inherent_data_providers = sp_inherents::InherentDataProviders::new();108109	let telemetry = config.telemetry_endpoints.clone()110		.filter(|x| !x.is_empty())111		.map(|endpoints| -> Result<_, sc_telemetry::Error> {112			let worker = TelemetryWorker::new(16)?;113			let telemetry = worker.handle().new_telemetry(endpoints);114			Ok((worker, telemetry))115		})116		.transpose()?;117118	let (client, backend, keystore_container, task_manager) =119		sc_service::new_full_parts::<Block, RuntimeApi, Executor>(120			&config,121			telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),122		)?;123	let client = Arc::new(client);124125	let telemetry = telemetry126		.map(|(worker, telemetry)| {127			task_manager.spawn_handle().spawn("telemetry", worker.run());128			telemetry129		});130131	let select_chain = sc_consensus::LongestChain::new(backend.clone());132133	let transaction_pool = sc_transaction_pool::BasicPool::new_full(134		config.transaction_pool.clone(),135		config.role.is_authority().into(),136		config.prometheus_registry(),137		task_manager.spawn_handle(),138		client.clone(),139	);140141	let pending_transactions: PendingTransactions142		= Some(Arc::new(Mutex::new(HashMap::new())));143144	let filter_pool: Option<FilterPool>145		= Some(Arc::new(Mutex::new(BTreeMap::new())));146147	let frontier_backend = open_frontier_backend(config)?;148149	let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import(150		client.clone(),151		&(client.clone() as Arc<_>),152		select_chain.clone(),153		telemetry.as_ref().map(|x| x.handle()),154	)?;155156	let frontier_block_import = FrontierBlockImport::new(157		grandpa_block_import.clone(),158		client.clone(),159		frontier_backend.clone(),160	);161162	let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(163		frontier_block_import, client.clone(),164	);165166	let import_queue = sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _>(167		ImportQueueParams {168			slot_duration: sc_consensus_aura::slot_duration(&*client)?,169			block_import: aura_block_import.clone(),170			justification_import: Some(Box::new(grandpa_block_import.clone())),171			client: client.clone(),172			inherent_data_providers: inherent_data_providers.clone(),173			spawner: &task_manager.spawn_essential_handle(),174			registry: config.prometheus_registry(),175			can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),176			check_for_equivocation: Default::default(),177			telemetry: telemetry.as_ref().map(|x| x.handle()),178		}179	)?;180181	Ok(sc_service::PartialComponents {182		client, backend, task_manager, import_queue, keystore_container,183		select_chain, transaction_pool, inherent_data_providers,184		other: (185			(aura_block_import, grandpa_link),186			pending_transactions,187			filter_pool,188			frontier_backend,189			telemetry,190		)191	})192}193194/// Builds a new service for a full client.195pub fn new_full(196	config: Configuration,197	cli: &Cli,198) -> Result<TaskManager, ServiceError> {199	let enable_dev_signer = cli.run.shared_params.dev;200201	let sc_service::PartialComponents {202		client, backend, mut task_manager, import_queue, keystore_container,203		select_chain, transaction_pool, inherent_data_providers,204		other: (consensus_result, pending_transactions, filter_pool, frontier_backend, mut telemetry),205	} = new_partial(&config, cli)?;206207	let (network, network_status_sinks, system_rpc_tx, network_starter) =208		sc_service::build_network(sc_service::BuildNetworkParams {209			config: &config,210			client: Arc::clone(&client),211			transaction_pool: Arc::clone(&transaction_pool),212			spawn_handle: task_manager.spawn_handle(),213			import_queue,214			on_demand: None,215			block_announce_validator_builder: None,216		})?;217218	if config.offchain_worker.enabled {219		sc_service::build_offchain_workers(220			&config, task_manager.spawn_handle(), Arc::clone(&client), network.clone(),221		);222	}223224	let role = config.role.clone();225	let force_authoring = config.force_authoring;226	let backoff_authoring_blocks: Option<()> = None;227	let name = config.network.node_name.clone();228	let enable_grandpa = !config.disable_grandpa;229	let prometheus_registry = config.prometheus_registry().cloned();230	let is_authority = role.is_authority();231	let subscription_task_executor = sc_rpc::SubscriptionTaskExecutor::new(task_manager.spawn_handle());232233	let rpc_extensions_builder = {234		let client = Arc::clone(&client);235		let pool = Arc::clone(&transaction_pool);236		let network = network.clone();237		let pending = pending_transactions.clone();238		let filter_pool = filter_pool.clone();239		let frontier_backend = frontier_backend.clone();240241		Box::new(move |deny_unsafe, _| {242			let deps = crate::rpc::FullDeps {243				client: Arc::clone(&client),244				pool: Arc::clone(&pool),245				deny_unsafe,246				is_authority,247				enable_dev_signer,248				network: network.clone(),249				pending_transactions: pending.clone(),250				filter_pool: filter_pool.clone(),251				backend: frontier_backend.clone(),252			};253			crate::rpc::create_full(254				deps,255				subscription_task_executor.clone()256			)257		})258	};259260	task_manager.spawn_essential_handle().spawn(261		"frontier-mapping-sync-worker",262		MappingSyncWorker::new(263			client.import_notification_stream(),264			Duration::new(6, 0),265			Arc::clone(&client),266			Arc::clone(&backend),267			frontier_backend.clone(),268		).for_each(|()| futures::future::ready(()))269	);270271	let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {272		network: network.clone(),273		client: Arc::clone(&client),274		keystore: keystore_container.sync_keystore(),275		task_manager: &mut task_manager,276		transaction_pool: Arc::clone(&transaction_pool),277		rpc_extensions_builder: rpc_extensions_builder,278		on_demand: None,279		remote_blockchain: None,280		backend, network_status_sinks, system_rpc_tx, config, telemetry: telemetry.as_mut(),281	})?;282283	// Spawn Frontier EthFilterApi maintenance task.284	if let Some(filter_pool) = filter_pool {285		// Each filter is allowed to stay in the pool for 100 blocks.286		const FILTER_RETAIN_THRESHOLD: u64 = 100;287		task_manager.spawn_essential_handle().spawn(288			"frontier-filter-pool",289			EthTask::filter_pool_task(290					Arc::clone(&client),291					filter_pool,292					FILTER_RETAIN_THRESHOLD,293			)294		);295	}296297	// Spawn Frontier pending transactions maintenance task (as essential, otherwise we leak).298	if let Some(pending_transactions) = pending_transactions {299		const TRANSACTION_RETAIN_THRESHOLD: u64 = 5;300		task_manager.spawn_essential_handle().spawn(301			"frontier-pending-transactions",302			EthTask::pending_transaction_task(303				Arc::clone(&client),304					pending_transactions,305					TRANSACTION_RETAIN_THRESHOLD,306				)307		);308	}309310	let (aura_block_import, grandpa_link) = consensus_result;311312	if role.is_authority() {313		let proposer = sc_basic_authorship::ProposerFactory::new(314			task_manager.spawn_handle(),315			Arc::clone(&client),316			Arc::clone(&transaction_pool),317			prometheus_registry.as_ref(),318			telemetry.as_ref().map(|x| x.handle()),319		);320321		let can_author_with =322			sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());323		let aura = sc_consensus_aura::start_aura::<AuraPair, _, _, _, _, _, _, _, _, _>(324			StartAuraParams {325				slot_duration: sc_consensus_aura::slot_duration(&*client)?,326				client: Arc::clone(&client),327				select_chain,328				block_import: aura_block_import,329				proposer_factory: proposer,330				sync_oracle: network.clone(),331				inherent_data_providers: inherent_data_providers.clone(),332				force_authoring,333				backoff_authoring_blocks,334				keystore: keystore_container.sync_keystore(),335				can_author_with,336				block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32),337				telemetry: telemetry.as_ref().map(|x| x.handle()),338			}339		)?;340341		// the AURA authoring task is considered essential, i.e. if it342		// fails we take down the service with it.343		task_manager.spawn_essential_handle().spawn_blocking("aura", aura);344345		// if the node isn't actively participating in consensus then it doesn't346		// need a keystore, regardless of which protocol we use below.347		let keystore = if role.is_authority() {348			Some(keystore_container.sync_keystore())349		} else {350			None351		};352353		let grandpa_config = sc_finality_grandpa::Config {354			// FIXME #1578 make this available through chainspec355			gossip_duration: Duration::from_millis(333),356			justification_period: 512,357			name: Some(name),358			observer_enabled: false,359			keystore,360			is_authority: role.is_authority(),361			telemetry: telemetry.as_ref().map(|x| x.handle()),362		};363364		if enable_grandpa {365			// start the full GRANDPA voter366			// NOTE: non-authorities could run the GRANDPA observer protocol, but at367			// this point the full voter should provide better guarantees of block368			// and vote data availability than the observer. The observer has not369			// been tested extensively yet and having most nodes in a network run it370			// could lead to finality stalls.371			let grandpa_config = sc_finality_grandpa::GrandpaParams {372				config: grandpa_config,373				link: grandpa_link,374				network,375				telemetry: telemetry.as_ref().map(|x| x.handle()),376				voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),377				prometheus_registry,378				shared_voter_state: SharedVoterState::empty(),379			};380381			// the GRANDPA voter task is considered infallible, i.e.382			// if it fails we take down the service with it.383			task_manager.spawn_essential_handle().spawn_blocking(384				"grandpa-voter",385				sc_finality_grandpa::run_grandpa_voter(grandpa_config)?386			);387		}388	}389390	network_starter.start_network();391	Ok(task_manager)392}393/// Builds a new service for a light client.394pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {395	let telemetry = config.telemetry_endpoints.clone()396		.filter(|x| !x.is_empty())397		.map(|endpoints| -> Result<_, sc_telemetry::Error> {398			let worker = TelemetryWorker::new(16)?;399			let telemetry = worker.handle().new_telemetry(endpoints);400			Ok((worker, telemetry))401		})402		.transpose()?;403404	let (client, backend, keystore_container, mut task_manager, on_demand) =405		sc_service::new_light_parts::<Block, RuntimeApi, Executor>(406			&config,407			telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),408		)?;409410	let mut telemetry = telemetry411		.map(|(worker, telemetry)| {412			task_manager.spawn_handle().spawn("telemetry", worker.run());413			telemetry414		});415416	let select_chain = sc_consensus::LongestChain::new(backend.clone());417418	let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(419		config.transaction_pool.clone(),420		config.prometheus_registry(),421		task_manager.spawn_handle(),422		client.clone(),423		on_demand.clone(),424	));425426	let (grandpa_block_import, _) = sc_finality_grandpa::block_import(427		client.clone(),428		&(client.clone() as Arc<_>),429		select_chain.clone(),430		telemetry.as_ref().map(|x| x.handle()),431	)?;432433	let import_queue = sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _>(434		ImportQueueParams {435			slot_duration: sc_consensus_aura::slot_duration(&*client)?,436			block_import: grandpa_block_import.clone(),437			justification_import: Some(Box::new(grandpa_block_import)),438			client: client.clone(),439			inherent_data_providers: InherentDataProviders::new(),440			spawner: &task_manager.spawn_essential_handle(),441			registry: config.prometheus_registry(),442			can_author_with: sp_consensus::NeverCanAuthor,443			check_for_equivocation: Default::default(),444			telemetry: telemetry.as_ref().map(|x| x.handle()),445		}446	)?;447448	let light_deps = crate::rpc::LightDeps {449		remote_blockchain: backend.remote_blockchain(),450		fetcher: on_demand.clone(),451		client: client.clone(),452		pool: transaction_pool.clone(),453	};454455	let rpc_extensions = crate::rpc::create_light(light_deps);456457	let (network, network_status_sinks, system_rpc_tx, network_starter) =458		sc_service::build_network(sc_service::BuildNetworkParams {459			config: &config,460			client: client.clone(),461			transaction_pool: transaction_pool.clone(),462			spawn_handle: task_manager.spawn_handle(),463			import_queue,464			on_demand: Some(on_demand.clone()),465			block_announce_validator_builder: None,466		})?;467468	if config.offchain_worker.enabled {469		sc_service::build_offchain_workers(470			&config, task_manager.spawn_handle(), client.clone(), network.clone(),471		);472	}473474	sc_service::spawn_tasks(sc_service::SpawnTasksParams {475		remote_blockchain: Some(backend.remote_blockchain()),476		transaction_pool,477		task_manager: &mut task_manager,478		on_demand: Some(on_demand),479		rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)),480		config,481		client,482		keystore: keystore_container.sync_keystore(),483		backend,484		network,485		network_status_sinks,486		system_rpc_tx,487		telemetry: telemetry.as_mut(),488	})?;489490	network_starter.start_network();491492	Ok(task_manager)493}