diff --git a/node/build.rs b/node/build.rs index e3bfe311..f9d839f9 100644 --- a/node/build.rs +++ b/node/build.rs @@ -1,7 +1,7 @@ use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; fn main() { - generate_cargo_keys(); + generate_cargo_keys(); - rerun_if_git_head_changed(); + rerun_if_git_head_changed(); } diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs index 58d09ca9..cfd62df1 100644 --- a/node/src/benchmarking.rs +++ b/node/src/benchmarking.rs @@ -38,154 +38,154 @@ use crate::client::Client; /// /// Note: Should only be used for benchmarking. pub struct RemarkBuilder { - client: Arc, + client: Arc, } impl RemarkBuilder { - /// Creates a new [`Self`] from the given client. - pub fn new(client: Arc) -> Self { - Self { client } - } + /// Creates a new [`Self`] from the given client. + pub fn new(client: Arc) -> Self { + Self { client } + } } impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder { - fn pallet(&self) -> &str { - "system" - } - - fn extrinsic(&self) -> &str { - "remark" - } - - fn build(&self, nonce: u32) -> std::result::Result { - let acc = ecdsa::Pair::from_string("//Bob", None).expect("static values are valid; qed"); - let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( - self.client.as_ref(), - acc, - SystemCall::remark { remark: vec![] }.into(), - nonce, - ) - .into(); - - Ok(extrinsic) - } + fn pallet(&self) -> &str { + "system" + } + + fn extrinsic(&self) -> &str { + "remark" + } + + fn build(&self, nonce: u32) -> std::result::Result { + let acc = ecdsa::Pair::from_string("//Bob", None).expect("static values are valid; qed"); + let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( + self.client.as_ref(), + acc, + SystemCall::remark { remark: vec![] }.into(), + nonce, + ) + .into(); + + Ok(extrinsic) + } } /// Generates `Balances::TransferKeepAlive` extrinsics for the benchmarks. /// /// Note: Should only be used for benchmarking. pub struct TransferKeepAliveBuilder { - client: Arc, - dest: AccountId, - value: Balance, + client: Arc, + dest: AccountId, + value: Balance, } impl TransferKeepAliveBuilder { - /// Creates a new [`Self`] from the given client. - pub fn new(client: Arc, dest: AccountId, value: Balance) -> Self { - Self { - client, - dest, - value, - } - } + /// Creates a new [`Self`] from the given client. + pub fn new(client: Arc, dest: AccountId, value: Balance) -> Self { + Self { + client, + dest, + value, + } + } } impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder { - fn pallet(&self) -> &str { - "balances" - } - - fn extrinsic(&self) -> &str { - "transfer_keep_alive" - } - - fn build(&self, nonce: u32) -> std::result::Result { - let acc = ecdsa::Pair::from_string("//Bob", None).expect("static values are valid; qed"); - let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( - self.client.as_ref(), - acc, - BalancesCall::transfer_keep_alive { - dest: self.dest, - value: self.value, - } - .into(), - nonce, - ) - .into(); - - Ok(extrinsic) - } + fn pallet(&self) -> &str { + "balances" + } + + fn extrinsic(&self) -> &str { + "transfer_keep_alive" + } + + fn build(&self, nonce: u32) -> std::result::Result { + let acc = ecdsa::Pair::from_string("//Bob", None).expect("static values are valid; qed"); + let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( + self.client.as_ref(), + acc, + BalancesCall::transfer_keep_alive { + dest: self.dest, + value: self.value, + } + .into(), + nonce, + ) + .into(); + + Ok(extrinsic) + } } /// Create a transaction using the given `call`. /// /// Note: Should only be used for benchmarking. pub fn create_benchmark_extrinsic( - client: &Client, - sender: ecdsa::Pair, - call: runtime::RuntimeCall, - nonce: u32, + client: &Client, + sender: ecdsa::Pair, + call: runtime::RuntimeCall, + nonce: u32, ) -> runtime::UncheckedExtrinsic { - let genesis_hash = client - .block_hash(0) - .ok() - .flatten() - .expect("Genesis block exists; qed"); - let best_hash = client.chain_info().best_hash; - let best_block = client.chain_info().best_number; - - let period = runtime::BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; - let extra: runtime::SignedExtra = ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from(Era::mortal( - period, - best_block.saturated_into(), - )), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ); - - let raw_payload = runtime::SignedPayload::from_raw( - call.clone(), - extra.clone(), - ( - (), - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis_hash, - best_hash, - (), - (), - (), - ), - ); - let signature = raw_payload.using_encoded(|e| sender.sign(e)); - - runtime::UncheckedExtrinsic::new_signed( - call, - AccountId20::from(sender.public()), - runtime::Signature::new(signature), - extra, - ) + let genesis_hash = client + .block_hash(0) + .ok() + .flatten() + .expect("Genesis block exists; qed"); + let best_hash = client.chain_info().best_hash; + let best_block = client.chain_info().best_number; + + let period = runtime::BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckMortality::::from(Era::mortal( + period, + best_block.saturated_into(), + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + let raw_payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|e| sender.sign(e)); + + runtime::UncheckedExtrinsic::new_signed( + call, + AccountId20::from(sender.public()), + runtime::Signature::new(signature), + extra, + ) } /// Generates inherent data for the `benchmark overhead` command. /// /// Note: Should only be used for benchmarking. pub fn inherent_benchmark_data() -> Result { - let mut inherent_data = InherentData::new(); - let d = Duration::from_millis(0); - let timestamp = sp_timestamp::InherentDataProvider::new(d.into()); + let mut inherent_data = InherentData::new(); + let d = Duration::from_millis(0); + let timestamp = sp_timestamp::InherentDataProvider::new(d.into()); - futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data)) - .map_err(|e| format!("creating inherent data: {:?}", e))?; - Ok(inherent_data) + futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data)) + .map_err(|e| format!("creating inherent data: {:?}", e))?; + Ok(inherent_data) } diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 316ac856..6bfdcf8c 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -13,7 +13,7 @@ use sp_runtime::traits::{IdentifyAccount, Verify}; use sp_state_machine::BasicExternalities; // Frontier use frontier_template_runtime::{ - AccountId, Balance, EnableManualSeal, RuntimeGenesisConfig, SS58Prefix, Signature, WASM_BINARY, + AccountId, Balance, EnableManualSeal, RuntimeGenesisConfig, SS58Prefix, Signature, WASM_BINARY, }; // The URL for the telemetry server. @@ -28,28 +28,28 @@ pub type DevChainSpec = sc_service::GenericChainSpec; /// Extension for the dev genesis config to support a custom changes to the genesis state. #[derive(Serialize, Deserialize)] pub struct DevGenesisExt { - /// Genesis config. - genesis_config: RuntimeGenesisConfig, - /// The flag that if enable manual-seal mode. - enable_manual_seal: Option, + /// Genesis config. + genesis_config: RuntimeGenesisConfig, + /// The flag that if enable manual-seal mode. + enable_manual_seal: Option, } impl sp_runtime::BuildStorage for DevGenesisExt { - fn assimilate_storage(&self, storage: &mut Storage) -> Result<(), String> { - BasicExternalities::execute_with_storage(storage, || { - if let Some(enable_manual_seal) = &self.enable_manual_seal { - EnableManualSeal::set(enable_manual_seal); - } - }); - self.genesis_config.assimilate_storage(storage) - } + fn assimilate_storage(&self, storage: &mut Storage) -> Result<(), String> { + BasicExternalities::execute_with_storage(storage, || { + if let Some(enable_manual_seal) = &self.enable_manual_seal { + EnableManualSeal::set(enable_manual_seal); + } + }); + self.genesis_config.assimilate_storage(storage) + } } /// Generate a crypto pair from seed. pub fn get_from_seed(seed: &str) -> ::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() } #[allow(dead_code)] @@ -60,218 +60,218 @@ type AccountPublic = ::Signer; #[allow(dead_code)] pub fn get_account_id_from_seed(seed: &str) -> AccountId where - AccountPublic: From<::Public>, + AccountPublic: From<::Public>, { - AccountPublic::from(get_from_seed::(seed)).into_account() + AccountPublic::from(get_from_seed::(seed)).into_account() } /// Generate an Aura authority key. pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { - (get_from_seed::(s), get_from_seed::(s)) + (get_from_seed::(s), get_from_seed::(s)) } fn properties() -> Properties { - let mut properties = Properties::new(); - properties.insert("tokenDecimals".into(), 18.into()); - properties.insert("ss58Format".into(), SS58Prefix::get().into()); - properties + let mut properties = Properties::new(); + properties.insert("tokenDecimals".into(), 18.into()); + properties.insert("ss58Format".into(), SS58Prefix::get().into()); + properties } const UNITS: Balance = 1_000_000_000_000_000_000; pub fn development_config(enable_manual_seal: Option) -> DevChainSpec { - let wasm_binary = WASM_BINARY.expect("WASM not available"); + let wasm_binary = WASM_BINARY.expect("WASM not available"); - DevChainSpec::from_genesis( - // Name - "Development", - // ID - "dev", - ChainType::Development, - move || { - DevGenesisExt { - genesis_config: testnet_genesis( - wasm_binary, - // Sudo account (Alith) - AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), - // Pre-funded accounts - vec![ - AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), // Alith - AccountId::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")), // Baltathar - AccountId::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")), // Charleth - AccountId::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")), // Dorothy - AccountId::from(hex!("Ff64d3F6efE2317EE2807d223a0Bdc4c0c49dfDB")), // Ethan - AccountId::from(hex!("C0F0f4ab324C46e55D02D0033343B4Be8A55532d")), // Faith - ], - // Initial PoA authorities - vec![authority_keys_from_seed("Alice")], - // Ethereum chain ID - SS58Prefix::get() as u64, - ), - enable_manual_seal, - } - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - None, - // Fork ID - None, - // Properties - Some(properties()), - // Extensions - None, - ) + DevChainSpec::from_genesis( + // Name + "Development", + // ID + "dev", + ChainType::Development, + move || { + DevGenesisExt { + genesis_config: testnet_genesis( + wasm_binary, + // Sudo account (Alith) + AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), + // Pre-funded accounts + vec![ + AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), // Alith + AccountId::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")), // Baltathar + AccountId::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")), // Charleth + AccountId::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")), // Dorothy + AccountId::from(hex!("Ff64d3F6efE2317EE2807d223a0Bdc4c0c49dfDB")), // Ethan + AccountId::from(hex!("C0F0f4ab324C46e55D02D0033343B4Be8A55532d")), // Faith + ], + // Initial PoA authorities + vec![authority_keys_from_seed("Alice")], + // Ethereum chain ID + SS58Prefix::get() as u64, + ), + enable_manual_seal, + } + }, + // Bootnodes + vec![], + // Telemetry + None, + // Protocol ID + None, + // Fork ID + None, + // Properties + Some(properties()), + // Extensions + None, + ) } pub fn local_testnet_config() -> ChainSpec { - let wasm_binary = WASM_BINARY.expect("WASM not available"); + let wasm_binary = WASM_BINARY.expect("WASM not available"); - ChainSpec::from_genesis( - // Name - "Local Testnet", - // ID - "local_testnet", - ChainType::Local, - move || { - testnet_genesis( - wasm_binary, - // Initial PoA authorities - // Sudo account (Alith) - AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), - // Pre-funded accounts - vec![ - AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), // Alith - AccountId::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")), // Baltathar - AccountId::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")), // Charleth - AccountId::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")), // Dorothy - AccountId::from(hex!("Ff64d3F6efE2317EE2807d223a0Bdc4c0c49dfDB")), // Ethan - AccountId::from(hex!("C0F0f4ab324C46e55D02D0033343B4Be8A55532d")), // Faith - ], - vec![ - authority_keys_from_seed("Alice"), - authority_keys_from_seed("Bob"), - ], - 42, - ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - None, - // Fork ID - None, - // Properties - None, - // Extensions - None, - ) + ChainSpec::from_genesis( + // Name + "Local Testnet", + // ID + "local_testnet", + ChainType::Local, + move || { + testnet_genesis( + wasm_binary, + // Initial PoA authorities + // Sudo account (Alith) + AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), + // Pre-funded accounts + vec![ + AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")), // Alith + AccountId::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")), // Baltathar + AccountId::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")), // Charleth + AccountId::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")), // Dorothy + AccountId::from(hex!("Ff64d3F6efE2317EE2807d223a0Bdc4c0c49dfDB")), // Ethan + AccountId::from(hex!("C0F0f4ab324C46e55D02D0033343B4Be8A55532d")), // Faith + ], + vec![ + authority_keys_from_seed("Alice"), + authority_keys_from_seed("Bob"), + ], + 42, + ) + }, + // Bootnodes + vec![], + // Telemetry + None, + // Protocol ID + None, + // Fork ID + None, + // Properties + None, + // Extensions + None, + ) } /// Configure initial storage state for FRAME modules. fn testnet_genesis( - wasm_binary: &[u8], - sudo_key: AccountId, - endowed_accounts: Vec, - initial_authorities: Vec<(AuraId, GrandpaId)>, - chain_id: u64, + wasm_binary: &[u8], + sudo_key: AccountId, + endowed_accounts: Vec, + initial_authorities: Vec<(AuraId, GrandpaId)>, + chain_id: u64, ) -> RuntimeGenesisConfig { - use frontier_template_runtime::{ - AuraConfig, BalancesConfig, EVMChainIdConfig, EVMConfig, GrandpaConfig, SudoConfig, - SystemConfig, - }; + use frontier_template_runtime::{ + AuraConfig, BalancesConfig, EVMChainIdConfig, EVMConfig, GrandpaConfig, SudoConfig, + SystemConfig, + }; - RuntimeGenesisConfig { - // System - system: SystemConfig { - // Add Wasm runtime to storage. - code: wasm_binary.to_vec(), - ..Default::default() - }, - sudo: SudoConfig { - // Assign network admin rights. - key: Some(sudo_key), - }, + RuntimeGenesisConfig { + // System + system: SystemConfig { + // Add Wasm runtime to storage. + code: wasm_binary.to_vec(), + ..Default::default() + }, + sudo: SudoConfig { + // Assign network admin rights. + key: Some(sudo_key), + }, - // Monetary - balances: BalancesConfig { - balances: endowed_accounts - .iter() - .cloned() - .map(|k| (k, 1_000_000 * UNITS)) - .collect(), - }, - transaction_payment: Default::default(), + // Monetary + balances: BalancesConfig { + balances: endowed_accounts + .iter() + .cloned() + .map(|k| (k, 1_000_000 * UNITS)) + .collect(), + }, + transaction_payment: Default::default(), - // Consensus - aura: AuraConfig { - authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), - }, - grandpa: GrandpaConfig { - authorities: initial_authorities - .iter() - .map(|x| (x.1.clone(), 1)) - .collect(), - ..Default::default() - }, + // Consensus + aura: AuraConfig { + authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), + }, + grandpa: GrandpaConfig { + authorities: initial_authorities + .iter() + .map(|x| (x.1.clone(), 1)) + .collect(), + ..Default::default() + }, - // EVM compatibility - evm_chain_id: EVMChainIdConfig { - chain_id, - ..Default::default() - }, - evm: EVMConfig { - accounts: { - let mut map = BTreeMap::new(); - map.insert( - // H160 address of Alice dev account - // Derived from SS58 (42 prefix) address - // SS58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY - // hex: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d - // Using the full hex key, truncating to the first 20 bytes (the first 40 hex chars) - H160::from_str("d43593c715fdd31c61141abd04a99fd6822c8558") - .expect("internal H160 is valid; qed"), - fp_evm::GenesisAccount { - balance: U256::from_str("0xffffffffffffffffffffffffffffffff") - .expect("internal U256 is valid; qed"), - code: Default::default(), - nonce: Default::default(), - storage: Default::default(), - }, - ); - map.insert( - // H160 address of CI test runner account - H160::from_str("6be02d1d3665660d22ff9624b7be0551ee1ac91b") - .expect("internal H160 is valid; qed"), - fp_evm::GenesisAccount { - balance: U256::from_str("0xffffffffffffffffffffffffffffffff") - .expect("internal U256 is valid; qed"), - code: Default::default(), - nonce: Default::default(), - storage: Default::default(), - }, - ); - map.insert( - // H160 address for benchmark usage - H160::from_str("1000000000000000000000000000000000000001") - .expect("internal H160 is valid; qed"), - fp_evm::GenesisAccount { - nonce: U256::from(1), - balance: U256::from(1_000_000_000_000_000_000_000_000u128), - storage: Default::default(), - code: vec![0x00], - }, - ); - map - }, - ..Default::default() - }, - ethereum: Default::default(), - dynamic_fee: Default::default(), - base_fee: Default::default(), - } + // EVM compatibility + evm_chain_id: EVMChainIdConfig { + chain_id, + ..Default::default() + }, + evm: EVMConfig { + accounts: { + let mut map = BTreeMap::new(); + map.insert( + // H160 address of Alice dev account + // Derived from SS58 (42 prefix) address + // SS58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + // hex: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d + // Using the full hex key, truncating to the first 20 bytes (the first 40 hex chars) + H160::from_str("d43593c715fdd31c61141abd04a99fd6822c8558") + .expect("internal H160 is valid; qed"), + fp_evm::GenesisAccount { + balance: U256::from_str("0xffffffffffffffffffffffffffffffff") + .expect("internal U256 is valid; qed"), + code: Default::default(), + nonce: Default::default(), + storage: Default::default(), + }, + ); + map.insert( + // H160 address of CI test runner account + H160::from_str("6be02d1d3665660d22ff9624b7be0551ee1ac91b") + .expect("internal H160 is valid; qed"), + fp_evm::GenesisAccount { + balance: U256::from_str("0xffffffffffffffffffffffffffffffff") + .expect("internal U256 is valid; qed"), + code: Default::default(), + nonce: Default::default(), + storage: Default::default(), + }, + ); + map.insert( + // H160 address for benchmark usage + H160::from_str("1000000000000000000000000000000000000001") + .expect("internal H160 is valid; qed"), + fp_evm::GenesisAccount { + nonce: U256::from(1), + balance: U256::from(1_000_000_000_000_000_000_000_000u128), + storage: Default::default(), + code: vec![0x00], + }, + ); + map + }, + ..Default::default() + }, + ethereum: Default::default(), + dynamic_fee: Default::default(), + base_fee: Default::default(), + } } diff --git a/node/src/cli.rs b/node/src/cli.rs index fcae8cfd..f639b2ac 100644 --- a/node/src/cli.rs +++ b/node/src/cli.rs @@ -3,66 +3,66 @@ use crate::service::EthConfiguration; /// Available Sealing methods. #[derive(Copy, Clone, Debug, Default, clap::ValueEnum)] pub enum Sealing { - /// Seal using rpc method. - #[default] - Manual, - /// Seal when transaction is executed. - Instant, + /// Seal using rpc method. + #[default] + Manual, + /// Seal when transaction is executed. + Instant, } #[derive(Debug, clap::Parser)] pub struct Cli { - #[command(subcommand)] - pub subcommand: Option, + #[command(subcommand)] + pub subcommand: Option, - #[allow(missing_docs)] - #[command(flatten)] - pub run: sc_cli::RunCmd, + #[allow(missing_docs)] + #[command(flatten)] + pub run: sc_cli::RunCmd, - /// Choose sealing method. - #[arg(long, value_enum, ignore_case = true)] - pub sealing: Option, + /// Choose sealing method. + #[arg(long, value_enum, ignore_case = true)] + pub sealing: Option, - #[command(flatten)] - pub eth: EthConfiguration, + #[command(flatten)] + pub eth: EthConfiguration, } #[derive(Debug, clap::Subcommand)] pub enum Subcommand { - /// Key management cli utilities - #[command(subcommand)] - Key(sc_cli::KeySubcommand), + /// Key management cli utilities + #[command(subcommand)] + Key(sc_cli::KeySubcommand), - /// Build a chain specification. - BuildSpec(sc_cli::BuildSpecCmd), + /// Build a chain specification. + BuildSpec(sc_cli::BuildSpecCmd), - /// Validate blocks. - CheckBlock(sc_cli::CheckBlockCmd), + /// Validate blocks. + CheckBlock(sc_cli::CheckBlockCmd), - /// Export blocks. - ExportBlocks(sc_cli::ExportBlocksCmd), + /// Export blocks. + ExportBlocks(sc_cli::ExportBlocksCmd), - /// Export the state of a given block into a chain spec. - ExportState(sc_cli::ExportStateCmd), + /// Export the state of a given block into a chain spec. + ExportState(sc_cli::ExportStateCmd), - /// Import blocks. - ImportBlocks(sc_cli::ImportBlocksCmd), + /// Import blocks. + ImportBlocks(sc_cli::ImportBlocksCmd), - /// Remove the whole chain. - PurgeChain(sc_cli::PurgeChainCmd), + /// Remove the whole chain. + PurgeChain(sc_cli::PurgeChainCmd), - /// Revert the chain to a previous state. - Revert(sc_cli::RevertCmd), + /// Revert the chain to a previous state. + Revert(sc_cli::RevertCmd), - /// Sub-commands concerned with benchmarking. - #[cfg(feature = "runtime-benchmarks")] - #[command(subcommand)] - Benchmark(frame_benchmarking_cli::BenchmarkCmd), + /// Sub-commands concerned with benchmarking. + #[cfg(feature = "runtime-benchmarks")] + #[command(subcommand)] + Benchmark(frame_benchmarking_cli::BenchmarkCmd), - /// Sub-commands concerned with benchmarking. - #[cfg(not(feature = "runtime-benchmarks"))] - Benchmark, + /// Sub-commands concerned with benchmarking. + #[cfg(not(feature = "runtime-benchmarks"))] + Benchmark, - /// Db meta columns information. - FrontierDb(fc_cli::FrontierDbCmd), + /// Db meta columns information. + FrontierDb(fc_cli::FrontierDbCmd), } diff --git a/node/src/client.rs b/node/src/client.rs index e4c9ee54..6b842653 100644 --- a/node/src/client.rs +++ b/node/src/client.rs @@ -10,7 +10,7 @@ use crate::eth::EthCompatRuntimeApiCollection; pub type FullBackend = sc_service::TFullBackend; /// Full client. pub type FullClient = - sc_service::TFullClient>; + sc_service::TFullClient>; pub type Client = FullClient; @@ -23,55 +23,55 @@ pub type HostFunctions = (); pub struct TemplateRuntimeExecutor; impl NativeExecutionDispatch for TemplateRuntimeExecutor { - type ExtendHostFunctions = HostFunctions; + type ExtendHostFunctions = HostFunctions; - fn dispatch(method: &str, data: &[u8]) -> Option> { - frontier_template_runtime::api::dispatch(method, data) - } + fn dispatch(method: &str, data: &[u8]) -> Option> { + frontier_template_runtime::api::dispatch(method, data) + } - fn native_version() -> NativeVersion { - frontier_template_runtime::native_version() - } + fn native_version() -> NativeVersion { + frontier_template_runtime::native_version() + } } /// A set of APIs that every runtimes must implement. pub trait BaseRuntimeApiCollection: - sp_api::ApiExt - + sp_api::Metadata - + sp_block_builder::BlockBuilder - + sp_offchain::OffchainWorkerApi - + sp_session::SessionKeys - + sp_transaction_pool::runtime_api::TaggedTransactionQueue + sp_api::ApiExt + + sp_api::Metadata + + sp_block_builder::BlockBuilder + + sp_offchain::OffchainWorkerApi + + sp_session::SessionKeys + + sp_transaction_pool::runtime_api::TaggedTransactionQueue { } impl BaseRuntimeApiCollection for Api where - Api: sp_api::ApiExt - + sp_api::Metadata - + sp_block_builder::BlockBuilder - + sp_offchain::OffchainWorkerApi - + sp_session::SessionKeys - + sp_transaction_pool::runtime_api::TaggedTransactionQueue + Api: sp_api::ApiExt + + sp_api::Metadata + + sp_block_builder::BlockBuilder + + sp_offchain::OffchainWorkerApi + + sp_session::SessionKeys + + sp_transaction_pool::runtime_api::TaggedTransactionQueue { } /// A set of APIs that template runtime must implement. pub trait RuntimeApiCollection: - BaseRuntimeApiCollection - + EthCompatRuntimeApiCollection - + sp_consensus_aura::AuraApi - + sp_consensus_grandpa::GrandpaApi - + frame_system_rpc_runtime_api::AccountNonceApi - + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + BaseRuntimeApiCollection + + EthCompatRuntimeApiCollection + + sp_consensus_aura::AuraApi + + sp_consensus_grandpa::GrandpaApi + + frame_system_rpc_runtime_api::AccountNonceApi + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi { } impl RuntimeApiCollection for Api where - Api: BaseRuntimeApiCollection - + EthCompatRuntimeApiCollection - + sp_consensus_aura::AuraApi - + sp_consensus_grandpa::GrandpaApi - + frame_system_rpc_runtime_api::AccountNonceApi - + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi + Api: BaseRuntimeApiCollection + + EthCompatRuntimeApiCollection + + sp_consensus_aura::AuraApi + + sp_consensus_grandpa::GrandpaApi + + frame_system_rpc_runtime_api::AccountNonceApi + + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi { } diff --git a/node/src/command.rs b/node/src/command.rs index f55f7622..8cdc2edd 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -23,230 +23,230 @@ use sc_service::DatabaseSource; use fc_db::kv::frontier_database_dir; use crate::{ - chain_spec, - cli::{Cli, Subcommand}, - service::{self, db_config_dir}, + chain_spec, + cli::{Cli, Subcommand}, + service::{self, db_config_dir}, }; #[cfg(feature = "runtime-benchmarks")] use crate::chain_spec::get_account_id_from_seed; impl SubstrateCli for Cli { - fn impl_name() -> String { - "Frontier Node".into() - } - - fn impl_version() -> String { - env!("SUBSTRATE_CLI_IMPL_VERSION").into() - } - - fn description() -> String { - env!("CARGO_PKG_DESCRIPTION").into() - } - - fn author() -> String { - env!("CARGO_PKG_AUTHORS").into() - } - - fn support_url() -> String { - "support.anonymous.an".into() - } - - fn copyright_start_year() -> i32 { - 2021 - } - - fn load_spec(&self, id: &str) -> Result, String> { - Ok(match id { - "dev" => { - let enable_manual_seal = self.sealing.map(|_| true); - Box::new(chain_spec::development_config(enable_manual_seal)) - } - "" | "local" => Box::new(chain_spec::local_testnet_config()), - path => Box::new(chain_spec::ChainSpec::from_json_file( - std::path::PathBuf::from(path), - )?), - }) - } + fn impl_name() -> String { + "Frontier Node".into() + } + + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() + } + + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() + } + + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } + + fn support_url() -> String { + "support.anonymous.an".into() + } + + fn copyright_start_year() -> i32 { + 2021 + } + + fn load_spec(&self, id: &str) -> Result, String> { + Ok(match id { + "dev" => { + let enable_manual_seal = self.sealing.map(|_| true); + Box::new(chain_spec::development_config(enable_manual_seal)) + } + "" | "local" => Box::new(chain_spec::local_testnet_config()), + path => Box::new(chain_spec::ChainSpec::from_json_file( + std::path::PathBuf::from(path), + )?), + }) + } } /// Parse and run command line arguments pub fn run() -> sc_cli::Result<()> { - let cli = Cli::from_args(); - - match &cli.subcommand { - Some(Subcommand::Key(cmd)) => cmd.run(&cli), - Some(Subcommand::BuildSpec(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) - } - Some(Subcommand::CheckBlock(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|mut config| { - let (client, _, import_queue, task_manager, _) = - service::new_chain_ops(&mut config, &cli.eth)?; - Ok((cmd.run(client, import_queue), task_manager)) - }) - } - Some(Subcommand::ExportBlocks(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|mut config| { - let (client, _, _, task_manager, _) = - service::new_chain_ops(&mut config, &cli.eth)?; - Ok((cmd.run(client, config.database), task_manager)) - }) - } - Some(Subcommand::ExportState(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|mut config| { - let (client, _, _, task_manager, _) = - service::new_chain_ops(&mut config, &cli.eth)?; - Ok((cmd.run(client, config.chain_spec), task_manager)) - }) - } - Some(Subcommand::ImportBlocks(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|mut config| { - let (client, _, import_queue, task_manager, _) = - service::new_chain_ops(&mut config, &cli.eth)?; - Ok((cmd.run(client, import_queue), task_manager)) - }) - } - Some(Subcommand::PurgeChain(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| { - // Remove Frontier offchain db - let db_config_dir = db_config_dir(&config); - match cli.eth.frontier_backend_type { - crate::eth::BackendType::KeyValue => { - let frontier_database_config = match config.database { - DatabaseSource::RocksDb { .. } => DatabaseSource::RocksDb { - path: frontier_database_dir(&db_config_dir, "db"), - cache_size: 0, - }, - DatabaseSource::ParityDb { .. } => DatabaseSource::ParityDb { - path: frontier_database_dir(&db_config_dir, "paritydb"), - }, - _ => { - return Err(format!( - "Cannot purge `{:?}` database", - config.database - ) - .into()) - } - }; - cmd.run(frontier_database_config)?; - } - crate::eth::BackendType::Sql => { - let db_path = db_config_dir.join("sql"); - match std::fs::remove_dir_all(&db_path) { - Ok(_) => { - println!("{:?} removed.", &db_path); - } - Err(ref err) if err.kind() == std::io::ErrorKind::NotFound => { - eprintln!("{:?} did not exist.", &db_path); - } - Err(err) => { - return Err(format!( - "Cannot purge `{:?}` database: {:?}", - db_path, err, - ) - .into()) - } - }; - } - }; - cmd.run(config.database) - }) - } - Some(Subcommand::Revert(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|mut config| { - let (client, backend, _, task_manager, _) = - service::new_chain_ops(&mut config, &cli.eth)?; - let aux_revert = Box::new(move |client, _, blocks| { - sc_consensus_grandpa::revert(client, blocks)?; - Ok(()) - }); - Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) - }) - } - #[cfg(feature = "runtime-benchmarks")] - Some(Subcommand::Benchmark(cmd)) => { - use crate::benchmarking::{ - inherent_benchmark_data, RemarkBuilder, TransferKeepAliveBuilder, - }; - use frame_benchmarking_cli::{ - BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE, - }; - use frontier_template_runtime::{Block, ExistentialDeposit}; - - let runner = cli.create_runner(cmd)?; - match cmd { - BenchmarkCmd::Pallet(cmd) => runner.sync_run(|config| cmd.run::(config)), - BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| { - let (client, _, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; - cmd.run(client) - }), - BenchmarkCmd::Storage(cmd) => runner.sync_run(|mut config| { - let (client, backend, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; - let db = backend.expose_db(); - let storage = backend.expose_storage(); - cmd.run(config, client, db, storage) - }), - BenchmarkCmd::Overhead(cmd) => runner.sync_run(|mut config| { - let (client, _, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; - let ext_builder = RemarkBuilder::new(client.clone()); - cmd.run( - config, - client, - inherent_benchmark_data()?, - Vec::new(), - &ext_builder, - ) - }), - BenchmarkCmd::Extrinsic(cmd) => runner.sync_run(|mut config| { - let (client, _, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; - // Register the *Remark* and *TKA* builders. - let ext_factory = ExtrinsicFactory(vec![ - Box::new(RemarkBuilder::new(client.clone())), - Box::new(TransferKeepAliveBuilder::new( - client.clone(), - get_account_id_from_seed::("Alice"), - ExistentialDeposit::get(), - )), - ]); - - cmd.run(client, inherent_benchmark_data()?, Vec::new(), &ext_factory) - }), - BenchmarkCmd::Machine(cmd) => { - runner.sync_run(|config| cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone())) - } - } - } - #[cfg(not(feature = "runtime-benchmarks"))] - Some(Subcommand::Benchmark) => Err("Benchmarking wasn't enabled when building the node. \ + let cli = Cli::from_args(); + + match &cli.subcommand { + Some(Subcommand::Key(cmd)) => cmd.run(&cli), + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) + } + Some(Subcommand::CheckBlock(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|mut config| { + let (client, _, import_queue, task_manager, _) = + service::new_chain_ops(&mut config, &cli.eth)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::ExportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|mut config| { + let (client, _, _, task_manager, _) = + service::new_chain_ops(&mut config, &cli.eth)?; + Ok((cmd.run(client, config.database), task_manager)) + }) + } + Some(Subcommand::ExportState(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|mut config| { + let (client, _, _, task_manager, _) = + service::new_chain_ops(&mut config, &cli.eth)?; + Ok((cmd.run(client, config.chain_spec), task_manager)) + }) + } + Some(Subcommand::ImportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|mut config| { + let (client, _, import_queue, task_manager, _) = + service::new_chain_ops(&mut config, &cli.eth)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| { + // Remove Frontier offchain db + let db_config_dir = db_config_dir(&config); + match cli.eth.frontier_backend_type { + crate::eth::BackendType::KeyValue => { + let frontier_database_config = match config.database { + DatabaseSource::RocksDb { .. } => DatabaseSource::RocksDb { + path: frontier_database_dir(&db_config_dir, "db"), + cache_size: 0, + }, + DatabaseSource::ParityDb { .. } => DatabaseSource::ParityDb { + path: frontier_database_dir(&db_config_dir, "paritydb"), + }, + _ => { + return Err(format!( + "Cannot purge `{:?}` database", + config.database + ) + .into()) + } + }; + cmd.run(frontier_database_config)?; + } + crate::eth::BackendType::Sql => { + let db_path = db_config_dir.join("sql"); + match std::fs::remove_dir_all(&db_path) { + Ok(_) => { + println!("{:?} removed.", &db_path); + } + Err(ref err) if err.kind() == std::io::ErrorKind::NotFound => { + eprintln!("{:?} did not exist.", &db_path); + } + Err(err) => { + return Err(format!( + "Cannot purge `{:?}` database: {:?}", + db_path, err, + ) + .into()) + } + }; + } + }; + cmd.run(config.database) + }) + } + Some(Subcommand::Revert(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|mut config| { + let (client, backend, _, task_manager, _) = + service::new_chain_ops(&mut config, &cli.eth)?; + let aux_revert = Box::new(move |client, _, blocks| { + sc_consensus_grandpa::revert(client, blocks)?; + Ok(()) + }); + Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) + }) + } + #[cfg(feature = "runtime-benchmarks")] + Some(Subcommand::Benchmark(cmd)) => { + use crate::benchmarking::{ + inherent_benchmark_data, RemarkBuilder, TransferKeepAliveBuilder, + }; + use frame_benchmarking_cli::{ + BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE, + }; + use frontier_template_runtime::{Block, ExistentialDeposit}; + + let runner = cli.create_runner(cmd)?; + match cmd { + BenchmarkCmd::Pallet(cmd) => runner.sync_run(|config| cmd.run::(config)), + BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| { + let (client, _, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; + cmd.run(client) + }), + BenchmarkCmd::Storage(cmd) => runner.sync_run(|mut config| { + let (client, backend, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; + let db = backend.expose_db(); + let storage = backend.expose_storage(); + cmd.run(config, client, db, storage) + }), + BenchmarkCmd::Overhead(cmd) => runner.sync_run(|mut config| { + let (client, _, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; + let ext_builder = RemarkBuilder::new(client.clone()); + cmd.run( + config, + client, + inherent_benchmark_data()?, + Vec::new(), + &ext_builder, + ) + }), + BenchmarkCmd::Extrinsic(cmd) => runner.sync_run(|mut config| { + let (client, _, _, _, _) = service::new_chain_ops(&mut config, &cli.eth)?; + // Register the *Remark* and *TKA* builders. + let ext_factory = ExtrinsicFactory(vec![ + Box::new(RemarkBuilder::new(client.clone())), + Box::new(TransferKeepAliveBuilder::new( + client.clone(), + get_account_id_from_seed::("Alice"), + ExistentialDeposit::get(), + )), + ]); + + cmd.run(client, inherent_benchmark_data()?, Vec::new(), &ext_factory) + }), + BenchmarkCmd::Machine(cmd) => { + runner.sync_run(|config| cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone())) + } + } + } + #[cfg(not(feature = "runtime-benchmarks"))] + Some(Subcommand::Benchmark) => Err("Benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." - .into()), - Some(Subcommand::FrontierDb(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|mut config| { - let (client, _, _, _, frontier_backend) = - service::new_chain_ops(&mut config, &cli.eth)?; - let frontier_backend = match frontier_backend { - fc_db::Backend::KeyValue(kv) => std::sync::Arc::new(kv), - _ => panic!("Only fc_db::Backend::KeyValue supported"), - }; - cmd.run(client, frontier_backend) - }) - } - None => { - let runner = cli.create_runner(&cli.run)?; - runner.run_node_until_exit(|config| async move { - service::build_full(config, cli.eth, cli.sealing) - .map_err(Into::into) - .await - }) - } - } + .into()), + Some(Subcommand::FrontierDb(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|mut config| { + let (client, _, _, _, frontier_backend) = + service::new_chain_ops(&mut config, &cli.eth)?; + let frontier_backend = match frontier_backend { + fc_db::Backend::KeyValue(kv) => std::sync::Arc::new(kv), + _ => panic!("Only fc_db::Backend::KeyValue supported"), + }; + cmd.run(client, frontier_backend) + }) + } + None => { + let runner = cli.create_runner(&cli.run)?; + runner.run_node_until_exit(|config| async move { + service::build_full(config, cli.eth, cli.sealing) + .map_err(Into::into) + .await + }) + } + } } diff --git a/node/src/eth.rs b/node/src/eth.rs index 7400943a..22bd6859 100644 --- a/node/src/eth.rs +++ b/node/src/eth.rs @@ -1,8 +1,8 @@ use std::{ - collections::BTreeMap, - path::PathBuf, - sync::{Arc, Mutex}, - time::Duration, + collections::BTreeMap, + path::PathBuf, + sync::{Arc, Mutex}, + time::Duration, }; use futures::{future, prelude::*}; @@ -25,187 +25,187 @@ use crate::client::{FullBackend, FullClient}; pub type FrontierBackend = fc_db::Backend; pub fn db_config_dir(config: &Configuration) -> PathBuf { - config.base_path.config_dir(config.chain_spec.id()) + config.base_path.config_dir(config.chain_spec.id()) } /// Avalailable frontier backend types. #[derive(Debug, Copy, Clone, Default, clap::ValueEnum)] pub enum BackendType { - /// Either RocksDb or ParityDb as per inherited from the global backend settings. - #[default] - KeyValue, - /// Sql database with custom log indexing. - Sql, + /// Either RocksDb or ParityDb as per inherited from the global backend settings. + #[default] + KeyValue, + /// Sql database with custom log indexing. + Sql, } /// The ethereum-compatibility configuration used to run a node. #[derive(Clone, Debug, clap::Parser)] pub struct EthConfiguration { - /// Maximum number of logs in a query. - #[arg(long, default_value = "10000")] - pub max_past_logs: u32, - - /// Maximum fee history cache size. - #[arg(long, default_value = "2048")] - pub fee_history_limit: u64, - - #[arg(long)] - pub enable_dev_signer: bool, - - /// The dynamic-fee pallet target gas price set by block author - #[arg(long, default_value = "1")] - pub target_gas_price: u64, - - /// Maximum allowed gas limit will be `block.gas_limit * execute_gas_limit_multiplier` - /// when using eth_call/eth_estimateGas. - #[arg(long, default_value = "10")] - pub execute_gas_limit_multiplier: u64, - - /// Size in bytes of the LRU cache for block data. - #[arg(long, default_value = "50")] - pub eth_log_block_cache: usize, - - /// Size in bytes of the LRU cache for transactions statuses data. - #[arg(long, default_value = "50")] - pub eth_statuses_cache: usize, - - /// Sets the frontier backend type (KeyValue or Sql) - #[arg(long, value_enum, ignore_case = true, default_value_t = BackendType::default())] - pub frontier_backend_type: BackendType, - - // Sets the SQL backend's pool size. - #[arg(long, default_value = "100")] - pub frontier_sql_backend_pool_size: u32, - - /// Sets the SQL backend's query timeout in number of VM ops. - #[arg(long, default_value = "10000000")] - pub frontier_sql_backend_num_ops_timeout: u32, - - /// Sets the SQL backend's auxiliary thread limit. - #[arg(long, default_value = "4")] - pub frontier_sql_backend_thread_count: u32, - - /// Sets the SQL backend's query timeout in number of VM ops. - /// Default value is 200MB. - #[arg(long, default_value = "209715200")] - pub frontier_sql_backend_cache_size: u64, + /// Maximum number of logs in a query. + #[arg(long, default_value = "10000")] + pub max_past_logs: u32, + + /// Maximum fee history cache size. + #[arg(long, default_value = "2048")] + pub fee_history_limit: u64, + + #[arg(long)] + pub enable_dev_signer: bool, + + /// The dynamic-fee pallet target gas price set by block author + #[arg(long, default_value = "1")] + pub target_gas_price: u64, + + /// Maximum allowed gas limit will be `block.gas_limit * execute_gas_limit_multiplier` + /// when using eth_call/eth_estimateGas. + #[arg(long, default_value = "10")] + pub execute_gas_limit_multiplier: u64, + + /// Size in bytes of the LRU cache for block data. + #[arg(long, default_value = "50")] + pub eth_log_block_cache: usize, + + /// Size in bytes of the LRU cache for transactions statuses data. + #[arg(long, default_value = "50")] + pub eth_statuses_cache: usize, + + /// Sets the frontier backend type (KeyValue or Sql) + #[arg(long, value_enum, ignore_case = true, default_value_t = BackendType::default())] + pub frontier_backend_type: BackendType, + + // Sets the SQL backend's pool size. + #[arg(long, default_value = "100")] + pub frontier_sql_backend_pool_size: u32, + + /// Sets the SQL backend's query timeout in number of VM ops. + #[arg(long, default_value = "10000000")] + pub frontier_sql_backend_num_ops_timeout: u32, + + /// Sets the SQL backend's auxiliary thread limit. + #[arg(long, default_value = "4")] + pub frontier_sql_backend_thread_count: u32, + + /// Sets the SQL backend's query timeout in number of VM ops. + /// Default value is 200MB. + #[arg(long, default_value = "209715200")] + pub frontier_sql_backend_cache_size: u64, } pub struct FrontierPartialComponents { - pub filter_pool: Option, - pub fee_history_cache: FeeHistoryCache, - pub fee_history_cache_limit: FeeHistoryCacheLimit, + pub filter_pool: Option, + pub fee_history_cache: FeeHistoryCache, + pub fee_history_cache_limit: FeeHistoryCacheLimit, } pub fn new_frontier_partial( - config: &EthConfiguration, + config: &EthConfiguration, ) -> Result { - Ok(FrontierPartialComponents { - filter_pool: Some(Arc::new(Mutex::new(BTreeMap::new()))), - fee_history_cache: Arc::new(Mutex::new(BTreeMap::new())), - fee_history_cache_limit: config.fee_history_limit, - }) + Ok(FrontierPartialComponents { + filter_pool: Some(Arc::new(Mutex::new(BTreeMap::new()))), + fee_history_cache: Arc::new(Mutex::new(BTreeMap::new())), + fee_history_cache_limit: config.fee_history_limit, + }) } /// A set of APIs that ethereum-compatible runtimes must implement. pub trait EthCompatRuntimeApiCollection: - sp_api::ApiExt - + fp_rpc::ConvertTransactionRuntimeApi - + fp_rpc::EthereumRuntimeRPCApi + sp_api::ApiExt + + fp_rpc::ConvertTransactionRuntimeApi + + fp_rpc::EthereumRuntimeRPCApi { } impl EthCompatRuntimeApiCollection for Api where - Api: sp_api::ApiExt - + fp_rpc::ConvertTransactionRuntimeApi - + fp_rpc::EthereumRuntimeRPCApi + Api: sp_api::ApiExt + + fp_rpc::ConvertTransactionRuntimeApi + + fp_rpc::EthereumRuntimeRPCApi { } pub async fn spawn_frontier_tasks( - task_manager: &TaskManager, - client: Arc>, - backend: Arc, - frontier_backend: FrontierBackend, - filter_pool: Option, - overrides: Arc>, - fee_history_cache: FeeHistoryCache, - fee_history_cache_limit: FeeHistoryCacheLimit, - sync: Arc>, - pubsub_notification_sinks: Arc< - fc_mapping_sync::EthereumBlockNotificationSinks< - fc_mapping_sync::EthereumBlockNotification, - >, - >, + task_manager: &TaskManager, + client: Arc>, + backend: Arc, + frontier_backend: FrontierBackend, + filter_pool: Option, + overrides: Arc>, + fee_history_cache: FeeHistoryCache, + fee_history_cache_limit: FeeHistoryCacheLimit, + sync: Arc>, + pubsub_notification_sinks: Arc< + fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + >, + >, ) where - RuntimeApi: ConstructRuntimeApi>, - RuntimeApi: Send + Sync + 'static, - RuntimeApi::RuntimeApi: EthCompatRuntimeApiCollection, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: EthCompatRuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, { - // Spawn main mapping sync worker background task. - match frontier_backend { - fc_db::Backend::KeyValue(b) => { - task_manager.spawn_essential_handle().spawn( - "frontier-mapping-sync-worker", - Some("frontier"), - fc_mapping_sync::kv::MappingSyncWorker::new( - client.import_notification_stream(), - Duration::new(6, 0), - client.clone(), - backend, - overrides.clone(), - Arc::new(b), - 3, - 0, - fc_mapping_sync::SyncStrategy::Normal, - sync, - pubsub_notification_sinks, - ) - .for_each(|()| future::ready(())), - ); - } - fc_db::Backend::Sql(b) => { - task_manager.spawn_essential_handle().spawn_blocking( - "frontier-mapping-sync-worker", - Some("frontier"), - fc_mapping_sync::sql::SyncWorker::run( - client.clone(), - backend, - Arc::new(b), - client.import_notification_stream(), - fc_mapping_sync::sql::SyncWorkerConfig { - read_notification_timeout: Duration::from_secs(10), - check_indexed_blocks_interval: Duration::from_secs(60), - }, - fc_mapping_sync::SyncStrategy::Parachain, - sync, - pubsub_notification_sinks, - ), - ); - } - } - - // Spawn Frontier EthFilterApi maintenance task. - if let Some(filter_pool) = filter_pool { - // Each filter is allowed to stay in the pool for 100 blocks. - const FILTER_RETAIN_THRESHOLD: u64 = 100; - task_manager.spawn_essential_handle().spawn( - "frontier-filter-pool", - Some("frontier"), - EthTask::filter_pool_task(client.clone(), filter_pool, FILTER_RETAIN_THRESHOLD), - ); - } - - // Spawn Frontier FeeHistory cache maintenance task. - task_manager.spawn_essential_handle().spawn( - "frontier-fee-history", - Some("frontier"), - EthTask::fee_history_task( - client, - overrides, - fee_history_cache, - fee_history_cache_limit, - ), - ); + // Spawn main mapping sync worker background task. + match frontier_backend { + fc_db::Backend::KeyValue(b) => { + task_manager.spawn_essential_handle().spawn( + "frontier-mapping-sync-worker", + Some("frontier"), + fc_mapping_sync::kv::MappingSyncWorker::new( + client.import_notification_stream(), + Duration::new(6, 0), + client.clone(), + backend, + overrides.clone(), + Arc::new(b), + 3, + 0, + fc_mapping_sync::SyncStrategy::Normal, + sync, + pubsub_notification_sinks, + ) + .for_each(|()| future::ready(())), + ); + } + fc_db::Backend::Sql(b) => { + task_manager.spawn_essential_handle().spawn_blocking( + "frontier-mapping-sync-worker", + Some("frontier"), + fc_mapping_sync::sql::SyncWorker::run( + client.clone(), + backend, + Arc::new(b), + client.import_notification_stream(), + fc_mapping_sync::sql::SyncWorkerConfig { + read_notification_timeout: Duration::from_secs(10), + check_indexed_blocks_interval: Duration::from_secs(60), + }, + fc_mapping_sync::SyncStrategy::Parachain, + sync, + pubsub_notification_sinks, + ), + ); + } + } + + // Spawn Frontier EthFilterApi maintenance task. + if let Some(filter_pool) = filter_pool { + // Each filter is allowed to stay in the pool for 100 blocks. + const FILTER_RETAIN_THRESHOLD: u64 = 100; + task_manager.spawn_essential_handle().spawn( + "frontier-filter-pool", + Some("frontier"), + EthTask::filter_pool_task(client.clone(), filter_pool, FILTER_RETAIN_THRESHOLD), + ); + } + + // Spawn Frontier FeeHistory cache maintenance task. + task_manager.spawn_essential_handle().spawn( + "frontier-fee-history", + Some("frontier"), + EthTask::fee_history_task( + client, + overrides, + fee_history_cache, + fee_history_cache_limit, + ), + ); } diff --git a/node/src/main.rs b/node/src/main.rs index 94c4643c..6f854fec 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -2,9 +2,9 @@ #![warn(missing_docs)] #![allow( - clippy::type_complexity, - clippy::too_many_arguments, - clippy::large_enum_variant + clippy::type_complexity, + clippy::too_many_arguments, + clippy::large_enum_variant )] #![cfg_attr(feature = "runtime-benchmarks", deny(unused_crate_dependencies))] @@ -19,5 +19,5 @@ mod rpc; mod service; fn main() -> sc_cli::Result<()> { - command::run() + command::run() } diff --git a/node/src/rpc/eth.rs b/node/src/rpc/eth.rs index caf7e478..cced7443 100644 --- a/node/src/rpc/eth.rs +++ b/node/src/rpc/eth.rs @@ -3,9 +3,9 @@ use std::{collections::BTreeMap, sync::Arc}; use jsonrpsee::RpcModule; // Substrate use sc_client_api::{ - backend::{Backend, StorageProvider}, - client::BlockchainEvents, - AuxStore, UsageProvider, + backend::{Backend, StorageProvider}, + client::BlockchainEvents, + AuxStore, UsageProvider, }; use sc_network::NetworkService; use sc_network_sync::SyncingService; @@ -27,170 +27,170 @@ use fp_rpc::{ConvertTransaction, ConvertTransactionRuntimeApi, EthereumRuntimeRP /// Extra dependencies for Ethereum compatibility. pub struct EthDeps { - /// The client instance to use. - pub client: Arc, - /// Transaction pool instance. - pub pool: Arc

, - /// Graph pool instance. - pub graph: Arc>, - /// Ethereum transaction converter. - pub converter: Option, - /// The Node authority flag - pub is_authority: bool, - /// Whether to enable dev signer - pub enable_dev_signer: bool, - /// Network service - pub network: Arc>, - /// Chain syncing service - pub sync: Arc>, - /// Frontier Backend. - pub frontier_backend: Arc>, - /// Ethereum data access overrides. - pub overrides: Arc>, - /// Cache for Ethereum block data. - pub block_data_cache: Arc>, - /// EthFilterApi pool. - pub filter_pool: Option, - /// Maximum number of logs in a query. - pub max_past_logs: u32, - /// Fee history cache. - pub fee_history_cache: FeeHistoryCache, - /// Maximum fee history cache size. - pub fee_history_cache_limit: FeeHistoryCacheLimit, - /// Maximum allowed gas limit will be ` block.gas_limit * execute_gas_limit_multiplier` when - /// using eth_call/eth_estimateGas. - pub execute_gas_limit_multiplier: u64, - /// Mandated parent hashes for a given block hash. - pub forced_parent_hashes: Option>, - /// Something that can create the inherent data providers for pending state - pub pending_create_inherent_data_providers: CIDP, + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Graph pool instance. + pub graph: Arc>, + /// Ethereum transaction converter. + pub converter: Option, + /// The Node authority flag + pub is_authority: bool, + /// Whether to enable dev signer + pub enable_dev_signer: bool, + /// Network service + pub network: Arc>, + /// Chain syncing service + pub sync: Arc>, + /// Frontier Backend. + pub frontier_backend: Arc>, + /// Ethereum data access overrides. + pub overrides: Arc>, + /// Cache for Ethereum block data. + pub block_data_cache: Arc>, + /// EthFilterApi pool. + pub filter_pool: Option, + /// Maximum number of logs in a query. + pub max_past_logs: u32, + /// Fee history cache. + pub fee_history_cache: FeeHistoryCache, + /// Maximum fee history cache size. + pub fee_history_cache_limit: FeeHistoryCacheLimit, + /// Maximum allowed gas limit will be ` block.gas_limit * execute_gas_limit_multiplier` when + /// using eth_call/eth_estimateGas. + pub execute_gas_limit_multiplier: u64, + /// Mandated parent hashes for a given block hash. + pub forced_parent_hashes: Option>, + /// Something that can create the inherent data providers for pending state + pub pending_create_inherent_data_providers: CIDP, } /// Instantiate Ethereum-compatible RPC extensions. pub fn create_eth( - mut io: RpcModule<()>, - deps: EthDeps, - subscription_task_executor: SubscriptionTaskExecutor, - pubsub_notification_sinks: Arc< - fc_mapping_sync::EthereumBlockNotificationSinks< - fc_mapping_sync::EthereumBlockNotification, - >, - >, + mut io: RpcModule<()>, + deps: EthDeps, + subscription_task_executor: SubscriptionTaskExecutor, + pubsub_notification_sinks: Arc< + fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + >, + >, ) -> Result, Box> where - B: BlockT, - C: CallApiAt + ProvideRuntimeApi, - C::Api: AuraApi - + BlockBuilderApi - + ConvertTransactionRuntimeApi - + EthereumRuntimeRPCApi, - C: HeaderBackend + HeaderMetadata, - C: BlockchainEvents + AuxStore + UsageProvider + StorageProvider + 'static, - BE: Backend + 'static, - P: TransactionPool + 'static, - A: ChainApi + 'static, - CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, - CIDP: CreateInherentDataProviders + Send + 'static, - EC: EthConfig, + B: BlockT, + C: CallApiAt + ProvideRuntimeApi, + C::Api: AuraApi + + BlockBuilderApi + + ConvertTransactionRuntimeApi + + EthereumRuntimeRPCApi, + C: HeaderBackend + HeaderMetadata, + C: BlockchainEvents + AuxStore + UsageProvider + StorageProvider + 'static, + BE: Backend + 'static, + P: TransactionPool + 'static, + A: ChainApi + 'static, + CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, + CIDP: CreateInherentDataProviders + Send + 'static, + EC: EthConfig, { - use fc_rpc::{ - pending::AuraConsensusDataProvider, Eth, EthApiServer, EthDevSigner, EthFilter, - EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, - Web3ApiServer, - }; - #[cfg(feature = "txpool")] - use fc_rpc::{TxPool, TxPoolApiServer}; + use fc_rpc::{ + pending::AuraConsensusDataProvider, Eth, EthApiServer, EthDevSigner, EthFilter, + EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, NetApiServer, Web3, + Web3ApiServer, + }; + #[cfg(feature = "txpool")] + use fc_rpc::{TxPool, TxPoolApiServer}; - let EthDeps { - client, - pool, - graph, - converter, - is_authority, - enable_dev_signer, - network, - sync, - frontier_backend, - overrides, - block_data_cache, - filter_pool, - max_past_logs, - fee_history_cache, - fee_history_cache_limit, - execute_gas_limit_multiplier, - forced_parent_hashes, - pending_create_inherent_data_providers, - } = deps; + let EthDeps { + client, + pool, + graph, + converter, + is_authority, + enable_dev_signer, + network, + sync, + frontier_backend, + overrides, + block_data_cache, + filter_pool, + max_past_logs, + fee_history_cache, + fee_history_cache_limit, + execute_gas_limit_multiplier, + forced_parent_hashes, + pending_create_inherent_data_providers, + } = deps; - let mut signers = Vec::new(); - if enable_dev_signer { - signers.push(Box::new(EthDevSigner::new()) as Box); - } + let mut signers = Vec::new(); + if enable_dev_signer { + signers.push(Box::new(EthDevSigner::new()) as Box); + } - io.merge( - Eth::::new( - client.clone(), - pool.clone(), - graph.clone(), - converter, - sync.clone(), - signers, - overrides.clone(), - frontier_backend.clone(), - is_authority, - block_data_cache.clone(), - fee_history_cache, - fee_history_cache_limit, - execute_gas_limit_multiplier, - forced_parent_hashes, - pending_create_inherent_data_providers, - Some(Box::new(AuraConsensusDataProvider::new(client.clone()))), - ) - .replace_config::() - .into_rpc(), - )?; + io.merge( + Eth::::new( + client.clone(), + pool.clone(), + graph.clone(), + converter, + sync.clone(), + signers, + overrides.clone(), + frontier_backend.clone(), + is_authority, + block_data_cache.clone(), + fee_history_cache, + fee_history_cache_limit, + execute_gas_limit_multiplier, + forced_parent_hashes, + pending_create_inherent_data_providers, + Some(Box::new(AuraConsensusDataProvider::new(client.clone()))), + ) + .replace_config::() + .into_rpc(), + )?; - if let Some(filter_pool) = filter_pool { - io.merge( - EthFilter::new( - client.clone(), - frontier_backend, - graph.clone(), - filter_pool, - 500_usize, // max stored filters - max_past_logs, - block_data_cache, - ) - .into_rpc(), - )?; - } + if let Some(filter_pool) = filter_pool { + io.merge( + EthFilter::new( + client.clone(), + frontier_backend, + graph.clone(), + filter_pool, + 500_usize, // max stored filters + max_past_logs, + block_data_cache, + ) + .into_rpc(), + )?; + } - io.merge( - EthPubSub::new( - pool, - client.clone(), - sync, - subscription_task_executor, - overrides, - pubsub_notification_sinks, - ) - .into_rpc(), - )?; + io.merge( + EthPubSub::new( + pool, + client.clone(), + sync, + subscription_task_executor, + overrides, + pubsub_notification_sinks, + ) + .into_rpc(), + )?; - io.merge( - Net::new( - client.clone(), - network, - // Whether to format the `peer_count` response as Hex (default) or not. - true, - ) - .into_rpc(), - )?; + io.merge( + Net::new( + client.clone(), + network, + // Whether to format the `peer_count` response as Hex (default) or not. + true, + ) + .into_rpc(), + )?; - io.merge(Web3::new(client.clone()).into_rpc())?; + io.merge(Web3::new(client.clone()).into_rpc())?; - #[cfg(feature = "txpool")] - io.merge(TxPool::new(client, graph).into_rpc())?; + #[cfg(feature = "txpool")] + io.merge(TxPool::new(client, graph).into_rpc())?; - Ok(io) + Ok(io) } diff --git a/node/src/rpc/mod.rs b/node/src/rpc/mod.rs index b655b1e8..cdf3cf1c 100644 --- a/node/src/rpc/mod.rs +++ b/node/src/rpc/mod.rs @@ -6,9 +6,9 @@ use futures::channel::mpsc; use jsonrpsee::RpcModule; // Substrate use sc_client_api::{ - backend::{Backend, StorageProvider}, - client::BlockchainEvents, - AuxStore, UsageProvider, + backend::{Backend, StorageProvider}, + client::BlockchainEvents, + AuxStore, UsageProvider, }; use sc_consensus_manual_seal::rpc::EngineCommand; use sc_rpc::SubscriptionTaskExecutor; @@ -28,87 +28,87 @@ pub use self::eth::{create_eth, overrides_handle, EthDeps}; /// Full client dependencies. pub struct FullDeps { - /// The client instance to use. - pub client: Arc, - /// Transaction pool instance. - pub pool: Arc

, - /// Whether to deny unsafe calls - pub deny_unsafe: DenyUnsafe, - /// Manual seal command sink - pub command_sink: Option>>, - /// Ethereum-compatibility specific dependencies. - pub eth: EthDeps, + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, + /// Manual seal command sink + pub command_sink: Option>>, + /// Ethereum-compatibility specific dependencies. + pub eth: EthDeps, } pub struct DefaultEthConfig(std::marker::PhantomData<(C, BE)>); impl fc_rpc::EthConfig for DefaultEthConfig where - C: StorageProvider + Sync + Send + 'static, - BE: Backend + 'static, + C: StorageProvider + Sync + Send + 'static, + BE: Backend + 'static, { - type EstimateGasAdapter = (); - type RuntimeStorageOverride = - fc_rpc::frontier_backend_client::SystemAccountId20StorageOverride; + type EstimateGasAdapter = (); + type RuntimeStorageOverride = + fc_rpc::frontier_backend_client::SystemAccountId20StorageOverride; } /// Instantiate all Full RPC extensions. pub fn create_full( - deps: FullDeps, - subscription_task_executor: SubscriptionTaskExecutor, - pubsub_notification_sinks: Arc< - fc_mapping_sync::EthereumBlockNotificationSinks< - fc_mapping_sync::EthereumBlockNotification, - >, - >, + deps: FullDeps, + subscription_task_executor: SubscriptionTaskExecutor, + pubsub_notification_sinks: Arc< + fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + >, + >, ) -> Result, Box> where - C: CallApiAt + ProvideRuntimeApi, - C::Api: sp_block_builder::BlockBuilder, - C::Api: sp_consensus_aura::AuraApi, - C::Api: substrate_frame_rpc_system::AccountNonceApi, - C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - C::Api: fp_rpc::ConvertTransactionRuntimeApi, - C::Api: fp_rpc::EthereumRuntimeRPCApi, - C: HeaderBackend + HeaderMetadata + 'static, - C: BlockchainEvents + AuxStore + UsageProvider + StorageProvider, - BE: Backend + 'static, - P: TransactionPool + 'static, - A: ChainApi + 'static, - CIDP: CreateInherentDataProviders + Send + 'static, - CT: fp_rpc::ConvertTransaction<::Extrinsic> + Send + Sync + 'static, + C: CallApiAt + ProvideRuntimeApi, + C::Api: sp_block_builder::BlockBuilder, + C::Api: sp_consensus_aura::AuraApi, + C::Api: substrate_frame_rpc_system::AccountNonceApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: fp_rpc::ConvertTransactionRuntimeApi, + C::Api: fp_rpc::EthereumRuntimeRPCApi, + C: HeaderBackend + HeaderMetadata + 'static, + C: BlockchainEvents + AuxStore + UsageProvider + StorageProvider, + BE: Backend + 'static, + P: TransactionPool + 'static, + A: ChainApi + 'static, + CIDP: CreateInherentDataProviders + Send + 'static, + CT: fp_rpc::ConvertTransaction<::Extrinsic> + Send + Sync + 'static, { - use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; - use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer}; - use substrate_frame_rpc_system::{System, SystemApiServer}; + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer}; + use substrate_frame_rpc_system::{System, SystemApiServer}; - let mut io = RpcModule::new(()); - let FullDeps { - client, - pool, - deny_unsafe, - command_sink, - eth, - } = deps; + let mut io = RpcModule::new(()); + let FullDeps { + client, + pool, + deny_unsafe, + command_sink, + eth, + } = deps; - io.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; - io.merge(TransactionPayment::new(client).into_rpc())?; + io.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; + io.merge(TransactionPayment::new(client).into_rpc())?; - if let Some(command_sink) = command_sink { - io.merge( - // We provide the rpc handler with the sending end of the channel to allow the rpc - // send EngineCommands to the background block authorship task. - ManualSeal::new(command_sink).into_rpc(), - )?; - } + if let Some(command_sink) = command_sink { + io.merge( + // We provide the rpc handler with the sending end of the channel to allow the rpc + // send EngineCommands to the background block authorship task. + ManualSeal::new(command_sink).into_rpc(), + )?; + } - // Ethereum compatibility RPCs - let io = create_eth::<_, _, _, _, _, _, _, DefaultEthConfig>( - io, - eth, - subscription_task_executor, - pubsub_notification_sinks, - )?; + // Ethereum compatibility RPCs + let io = create_eth::<_, _, _, _, _, _, _, DefaultEthConfig>( + io, + eth, + subscription_task_executor, + pubsub_notification_sinks, + )?; - Ok(io) + Ok(io) } diff --git a/node/src/service.rs b/node/src/service.rs index 81e22104..0c0e08bc 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -19,16 +19,16 @@ use sp_core::U256; use frontier_template_runtime::{opaque::Block, Hash, TransactionConverter}; use crate::{ - cli::Sealing, - client::{BaseRuntimeApiCollection, FullBackend, FullClient, RuntimeApiCollection}, - eth::{ - new_frontier_partial, spawn_frontier_tasks, BackendType, EthCompatRuntimeApiCollection, - FrontierBackend, FrontierBlockImport, FrontierPartialComponents, - }, + cli::Sealing, + client::{BaseRuntimeApiCollection, FullBackend, FullClient, RuntimeApiCollection}, + eth::{ + new_frontier_partial, spawn_frontier_tasks, BackendType, EthCompatRuntimeApiCollection, + FrontierBackend, FrontierBlockImport, FrontierPartialComponents, + }, }; pub use crate::{ - client::{Client, TemplateRuntimeExecutor}, - eth::{db_config_dir, EthConfiguration}, + client::{Client, TemplateRuntimeExecutor}, + eth::{db_config_dir, EthConfiguration}, }; type BasicImportQueue = sc_consensus::DefaultImportQueue; @@ -36,7 +36,7 @@ type FullPool = sc_transaction_pool::FullPool; type FullSelectChain = sc_consensus::LongestChain; type GrandpaBlockImport = - sc_consensus_grandpa::GrandpaBlockImport; + sc_consensus_grandpa::GrandpaBlockImport; type GrandpaLinkHalf = sc_consensus_grandpa::LinkHalf; type BoxBlockImport = sc_consensus::BoxBlockImport; @@ -45,685 +45,685 @@ type BoxBlockImport = sc_consensus::BoxBlockImport; const GRANDPA_JUSTIFICATION_PERIOD: u32 = 512; pub fn new_partial( - config: &Configuration, - eth_config: &EthConfiguration, - build_import_queue: BIQ, + config: &Configuration, + eth_config: &EthConfiguration, + build_import_queue: BIQ, ) -> Result< - PartialComponents< - FullClient, - FullBackend, - FullSelectChain, - BasicImportQueue, - FullPool>, - ( - Option, - BoxBlockImport, - GrandpaLinkHalf>, - FrontierBackend, - Arc>, - ), - >, - ServiceError, + PartialComponents< + FullClient, + FullBackend, + FullSelectChain, + BasicImportQueue, + FullPool>, + ( + Option, + BoxBlockImport, + GrandpaLinkHalf>, + FrontierBackend, + Arc>, + ), + >, + ServiceError, > where - RuntimeApi: ConstructRuntimeApi>, - RuntimeApi: Send + Sync + 'static, - RuntimeApi::RuntimeApi: BaseRuntimeApiCollection + EthCompatRuntimeApiCollection, - Executor: NativeExecutionDispatch + 'static, - BIQ: FnOnce( - Arc>, - &Configuration, - &EthConfiguration, - &TaskManager, - Option, - GrandpaBlockImport>, - ) -> Result<(BasicImportQueue, BoxBlockImport), ServiceError>, + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: BaseRuntimeApiCollection + EthCompatRuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, + BIQ: FnOnce( + Arc>, + &Configuration, + &EthConfiguration, + &TaskManager, + Option, + GrandpaBlockImport>, + ) -> Result<(BasicImportQueue, BoxBlockImport), ServiceError>, { - let telemetry = config - .telemetry_endpoints - .clone() - .filter(|x| !x.is_empty()) - .map(|endpoints| -> Result<_, sc_telemetry::Error> { - let worker = TelemetryWorker::new(16)?; - let telemetry = worker.handle().new_telemetry(endpoints); - Ok((worker, telemetry)) - }) - .transpose()?; - - let executor = sc_service::new_native_or_wasm_executor(config); - - let (client, backend, keystore_container, task_manager) = - sc_service::new_full_parts::( - config, - telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), - executor, - )?; - let client = Arc::new(client); - - let telemetry = telemetry.map(|(worker, telemetry)| { - task_manager - .spawn_handle() - .spawn("telemetry", None, worker.run()); - telemetry - }); - - let select_chain = sc_consensus::LongestChain::new(backend.clone()); - let (grandpa_block_import, grandpa_link) = sc_consensus_grandpa::block_import( - client.clone(), - GRANDPA_JUSTIFICATION_PERIOD, - &client, - select_chain.clone(), - telemetry.as_ref().map(|x| x.handle()), - )?; - - let overrides = crate::rpc::overrides_handle(client.clone()); - let frontier_backend = match eth_config.frontier_backend_type { - BackendType::KeyValue => FrontierBackend::KeyValue(fc_db::kv::Backend::open( - Arc::clone(&client), - &config.database, - &db_config_dir(config), - )?), - BackendType::Sql => { - let db_path = db_config_dir(config).join("sql"); - std::fs::create_dir_all(&db_path).expect("failed creating sql db directory"); - let backend = futures::executor::block_on(fc_db::sql::Backend::new( - fc_db::sql::BackendConfig::Sqlite(fc_db::sql::SqliteBackendConfig { - path: Path::new("sqlite:///") - .join(db_path) - .join("frontier.db3") - .to_str() - .unwrap(), - create_if_missing: true, - thread_count: eth_config.frontier_sql_backend_thread_count, - cache_size: eth_config.frontier_sql_backend_cache_size, - }), - eth_config.frontier_sql_backend_pool_size, - std::num::NonZeroU32::new(eth_config.frontier_sql_backend_num_ops_timeout), - overrides.clone(), - )) - .unwrap_or_else(|err| panic!("failed creating sql backend: {:?}", err)); - FrontierBackend::Sql(backend) - } - }; - - let (import_queue, block_import) = build_import_queue( - client.clone(), - config, - eth_config, - &task_manager, - telemetry.as_ref().map(|x| x.handle()), - grandpa_block_import, - )?; - - let transaction_pool = sc_transaction_pool::BasicPool::new_full( - config.transaction_pool.clone(), - config.role.is_authority().into(), - config.prometheus_registry(), - task_manager.spawn_essential_handle(), - client.clone(), - ); - - Ok(PartialComponents { - client, - backend, - keystore_container, - task_manager, - select_chain, - import_queue, - transaction_pool, - other: ( - telemetry, - block_import, - grandpa_link, - frontier_backend, - overrides, - ), - }) + let telemetry = config + .telemetry_endpoints + .clone() + .filter(|x| !x.is_empty()) + .map(|endpoints| -> Result<_, sc_telemetry::Error> { + let worker = TelemetryWorker::new(16)?; + let telemetry = worker.handle().new_telemetry(endpoints); + Ok((worker, telemetry)) + }) + .transpose()?; + + let executor = sc_service::new_native_or_wasm_executor(config); + + let (client, backend, keystore_container, task_manager) = + sc_service::new_full_parts::( + config, + telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, + )?; + let client = Arc::new(client); + + let telemetry = telemetry.map(|(worker, telemetry)| { + task_manager + .spawn_handle() + .spawn("telemetry", None, worker.run()); + telemetry + }); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + let (grandpa_block_import, grandpa_link) = sc_consensus_grandpa::block_import( + client.clone(), + GRANDPA_JUSTIFICATION_PERIOD, + &client, + select_chain.clone(), + telemetry.as_ref().map(|x| x.handle()), + )?; + + let overrides = crate::rpc::overrides_handle(client.clone()); + let frontier_backend = match eth_config.frontier_backend_type { + BackendType::KeyValue => FrontierBackend::KeyValue(fc_db::kv::Backend::open( + Arc::clone(&client), + &config.database, + &db_config_dir(config), + )?), + BackendType::Sql => { + let db_path = db_config_dir(config).join("sql"); + std::fs::create_dir_all(&db_path).expect("failed creating sql db directory"); + let backend = futures::executor::block_on(fc_db::sql::Backend::new( + fc_db::sql::BackendConfig::Sqlite(fc_db::sql::SqliteBackendConfig { + path: Path::new("sqlite:///") + .join(db_path) + .join("frontier.db3") + .to_str() + .unwrap(), + create_if_missing: true, + thread_count: eth_config.frontier_sql_backend_thread_count, + cache_size: eth_config.frontier_sql_backend_cache_size, + }), + eth_config.frontier_sql_backend_pool_size, + std::num::NonZeroU32::new(eth_config.frontier_sql_backend_num_ops_timeout), + overrides.clone(), + )) + .unwrap_or_else(|err| panic!("failed creating sql backend: {:?}", err)); + FrontierBackend::Sql(backend) + } + }; + + let (import_queue, block_import) = build_import_queue( + client.clone(), + config, + eth_config, + &task_manager, + telemetry.as_ref().map(|x| x.handle()), + grandpa_block_import, + )?; + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.role.is_authority().into(), + config.prometheus_registry(), + task_manager.spawn_essential_handle(), + client.clone(), + ); + + Ok(PartialComponents { + client, + backend, + keystore_container, + task_manager, + select_chain, + import_queue, + transaction_pool, + other: ( + telemetry, + block_import, + grandpa_link, + frontier_backend, + overrides, + ), + }) } /// Build the import queue for the template runtime (aura + grandpa). pub fn build_aura_grandpa_import_queue( - client: Arc>, - config: &Configuration, - eth_config: &EthConfiguration, - task_manager: &TaskManager, - telemetry: Option, - grandpa_block_import: GrandpaBlockImport>, + client: Arc>, + config: &Configuration, + eth_config: &EthConfiguration, + task_manager: &TaskManager, + telemetry: Option, + grandpa_block_import: GrandpaBlockImport>, ) -> Result<(BasicImportQueue, BoxBlockImport), ServiceError> where - RuntimeApi: ConstructRuntimeApi>, - RuntimeApi: Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiCollection, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, { - let frontier_block_import = - FrontierBlockImport::new(grandpa_block_import.clone(), client.clone()); - - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let target_gas_price = eth_config.target_gas_price; - let create_inherent_data_providers = move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((slot, timestamp, dynamic_fee)) - }; - - let import_queue = sc_consensus_aura::import_queue::( - sc_consensus_aura::ImportQueueParams { - block_import: frontier_block_import.clone(), - justification_import: Some(Box::new(grandpa_block_import)), - client, - create_inherent_data_providers, - spawner: &task_manager.spawn_essential_handle(), - registry: config.prometheus_registry(), - check_for_equivocation: Default::default(), - telemetry, - compatibility_mode: sc_consensus_aura::CompatibilityMode::None, - }, - ) - .map_err::(Into::into)?; - - Ok((import_queue, Box::new(frontier_block_import))) + let frontier_block_import = + FrontierBlockImport::new(grandpa_block_import.clone(), client.clone()); + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + let target_gas_price = eth_config.target_gas_price; + let create_inherent_data_providers = move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); + Ok((slot, timestamp, dynamic_fee)) + }; + + let import_queue = sc_consensus_aura::import_queue::( + sc_consensus_aura::ImportQueueParams { + block_import: frontier_block_import.clone(), + justification_import: Some(Box::new(grandpa_block_import)), + client, + create_inherent_data_providers, + spawner: &task_manager.spawn_essential_handle(), + registry: config.prometheus_registry(), + check_for_equivocation: Default::default(), + telemetry, + compatibility_mode: sc_consensus_aura::CompatibilityMode::None, + }, + ) + .map_err::(Into::into)?; + + Ok((import_queue, Box::new(frontier_block_import))) } /// Build the import queue for the template runtime (manual seal). pub fn build_manual_seal_import_queue( - client: Arc>, - config: &Configuration, - _eth_config: &EthConfiguration, - task_manager: &TaskManager, - _telemetry: Option, - _grandpa_block_import: GrandpaBlockImport>, + client: Arc>, + config: &Configuration, + _eth_config: &EthConfiguration, + task_manager: &TaskManager, + _telemetry: Option, + _grandpa_block_import: GrandpaBlockImport>, ) -> Result<(BasicImportQueue, BoxBlockImport), ServiceError> where - RuntimeApi: ConstructRuntimeApi>, - RuntimeApi: Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiCollection, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, { - let frontier_block_import = FrontierBlockImport::new(client.clone(), client); - Ok(( - sc_consensus_manual_seal::import_queue( - Box::new(frontier_block_import.clone()), - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - ), - Box::new(frontier_block_import), - )) + let frontier_block_import = FrontierBlockImport::new(client.clone(), client); + Ok(( + sc_consensus_manual_seal::import_queue( + Box::new(frontier_block_import.clone()), + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + ), + Box::new(frontier_block_import), + )) } /// Builds a new service for a full client. pub async fn new_full( - mut config: Configuration, - eth_config: EthConfiguration, - sealing: Option, + mut config: Configuration, + eth_config: EthConfiguration, + sealing: Option, ) -> Result where - RuntimeApi: ConstructRuntimeApi>, - RuntimeApi: Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiCollection, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, { - let build_import_queue = if sealing.is_some() { - build_manual_seal_import_queue:: - } else { - build_aura_grandpa_import_queue:: - }; - - let PartialComponents { - client, - backend, - mut task_manager, - import_queue, - keystore_container, - select_chain, - transaction_pool, - other: (mut telemetry, block_import, grandpa_link, frontier_backend, overrides), - } = new_partial(&config, ð_config, build_import_queue)?; - - let FrontierPartialComponents { - filter_pool, - fee_history_cache, - fee_history_cache_limit, - } = new_frontier_partial(ð_config)?; - - let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network); - let grandpa_protocol_name = sc_consensus_grandpa::protocol_standard_name( - &client.block_hash(0)?.expect("Genesis block exists; qed"), - &config.chain_spec, - ); - - let warp_sync_params = if sealing.is_some() { - None - } else { - net_config.add_notification_protocol(sc_consensus_grandpa::grandpa_peers_set_config( - grandpa_protocol_name.clone(), - )); - let warp_sync: Arc> = - Arc::new(sc_consensus_grandpa::warp_proof::NetworkProvider::new( - backend.clone(), - grandpa_link.shared_authority_set().clone(), - Vec::default(), - )); - Some(WarpSyncParams::WithProvider(warp_sync)) - }; - - let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = - sc_service::build_network(sc_service::BuildNetworkParams { - config: &config, - net_config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - spawn_handle: task_manager.spawn_handle(), - import_queue, - block_announce_validator_builder: None, - warp_sync_params, - })?; - - if config.offchain_worker.enabled { - task_manager.spawn_handle().spawn( - "offchain-workers-runner", - "offchain-worker", - sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions { - runtime_api_provider: client.clone(), - is_validator: config.role.is_authority(), - keystore: Some(keystore_container.keystore()), - offchain_db: backend.offchain_storage(), - transaction_pool: Some(OffchainTransactionPoolFactory::new( - transaction_pool.clone(), - )), - network_provider: network.clone(), - enable_http_requests: true, - custom_extensions: |_| vec![], - }) - .run(client.clone(), task_manager.spawn_handle()) - .boxed(), - ); - } - - let role = config.role.clone(); - let force_authoring = config.force_authoring; - let name = config.network.node_name.clone(); - let enable_grandpa = !config.disable_grandpa && sealing.is_none(); - let prometheus_registry = config.prometheus_registry().cloned(); - - // Channel for the rpc handler to communicate with the authorship task. - let (command_sink, commands_stream) = mpsc::channel(1000); - - // Sinks for pubsub notifications. - // Everytime a new subscription is created, a new mpsc channel is added to the sink pool. - // The MappingSyncWorker sends through the channel on block import and the subscription emits a notification to the subscriber on receiving a message through this channel. - // This way we avoid race conditions when using native substrate block import notification stream. - let pubsub_notification_sinks: fc_mapping_sync::EthereumBlockNotificationSinks< - fc_mapping_sync::EthereumBlockNotification, - > = Default::default(); - let pubsub_notification_sinks = Arc::new(pubsub_notification_sinks); - - // for ethereum-compatibility rpc. - config.rpc_id_provider = Some(Box::new(fc_rpc::EthereumSubIdProvider)); - - let rpc_builder = { - let client = client.clone(); - let pool = transaction_pool.clone(); - let network = network.clone(); - let sync_service = sync_service.clone(); - - let is_authority = role.is_authority(); - let enable_dev_signer = eth_config.enable_dev_signer; - let max_past_logs = eth_config.max_past_logs; - let execute_gas_limit_multiplier = eth_config.execute_gas_limit_multiplier; - let filter_pool = filter_pool.clone(); - let frontier_backend = frontier_backend.clone(); - let pubsub_notification_sinks = pubsub_notification_sinks.clone(); - let overrides = overrides.clone(); - let fee_history_cache = fee_history_cache.clone(); - let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new( - task_manager.spawn_handle(), - overrides.clone(), - eth_config.eth_log_block_cache, - eth_config.eth_statuses_cache, - prometheus_registry.clone(), - )); - - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let target_gas_price = eth_config.target_gas_price; - let pending_create_inherent_data_providers = move |_, ()| async move { - let current = sp_timestamp::InherentDataProvider::from_system_time(); - let next_slot = current.timestamp().as_millis() + slot_duration.as_millis(); - let timestamp = sp_timestamp::InherentDataProvider::new(next_slot.into()); - let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + let build_import_queue = if sealing.is_some() { + build_manual_seal_import_queue:: + } else { + build_aura_grandpa_import_queue:: + }; + + let PartialComponents { + client, + backend, + mut task_manager, + import_queue, + keystore_container, + select_chain, + transaction_pool, + other: (mut telemetry, block_import, grandpa_link, frontier_backend, overrides), + } = new_partial(&config, ð_config, build_import_queue)?; + + let FrontierPartialComponents { + filter_pool, + fee_history_cache, + fee_history_cache_limit, + } = new_frontier_partial(ð_config)?; + + let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network); + let grandpa_protocol_name = sc_consensus_grandpa::protocol_standard_name( + &client.block_hash(0)?.expect("Genesis block exists; qed"), + &config.chain_spec, + ); + + let warp_sync_params = if sealing.is_some() { + None + } else { + net_config.add_notification_protocol(sc_consensus_grandpa::grandpa_peers_set_config( + grandpa_protocol_name.clone(), + )); + let warp_sync: Arc> = + Arc::new(sc_consensus_grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + grandpa_link.shared_authority_set().clone(), + Vec::default(), + )); + Some(WarpSyncParams::WithProvider(warp_sync)) + }; + + let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + net_config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + block_announce_validator_builder: None, + warp_sync_params, + })?; + + if config.offchain_worker.enabled { + task_manager.spawn_handle().spawn( + "offchain-workers-runner", + "offchain-worker", + sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions { + runtime_api_provider: client.clone(), + is_validator: config.role.is_authority(), + keystore: Some(keystore_container.keystore()), + offchain_db: backend.offchain_storage(), + transaction_pool: Some(OffchainTransactionPoolFactory::new( + transaction_pool.clone(), + )), + network_provider: network.clone(), + enable_http_requests: true, + custom_extensions: |_| vec![], + }) + .run(client.clone(), task_manager.spawn_handle()) + .boxed(), + ); + } + + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa && sealing.is_none(); + let prometheus_registry = config.prometheus_registry().cloned(); + + // Channel for the rpc handler to communicate with the authorship task. + let (command_sink, commands_stream) = mpsc::channel(1000); + + // Sinks for pubsub notifications. + // Everytime a new subscription is created, a new mpsc channel is added to the sink pool. + // The MappingSyncWorker sends through the channel on block import and the subscription emits a notification to the subscriber on receiving a message through this channel. + // This way we avoid race conditions when using native substrate block import notification stream. + let pubsub_notification_sinks: fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + > = Default::default(); + let pubsub_notification_sinks = Arc::new(pubsub_notification_sinks); + + // for ethereum-compatibility rpc. + config.rpc_id_provider = Some(Box::new(fc_rpc::EthereumSubIdProvider)); + + let rpc_builder = { + let client = client.clone(); + let pool = transaction_pool.clone(); + let network = network.clone(); + let sync_service = sync_service.clone(); + + let is_authority = role.is_authority(); + let enable_dev_signer = eth_config.enable_dev_signer; + let max_past_logs = eth_config.max_past_logs; + let execute_gas_limit_multiplier = eth_config.execute_gas_limit_multiplier; + let filter_pool = filter_pool.clone(); + let frontier_backend = frontier_backend.clone(); + let pubsub_notification_sinks = pubsub_notification_sinks.clone(); + let overrides = overrides.clone(); + let fee_history_cache = fee_history_cache.clone(); + let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new( + task_manager.spawn_handle(), + overrides.clone(), + eth_config.eth_log_block_cache, + eth_config.eth_statuses_cache, + prometheus_registry.clone(), + )); + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + let target_gas_price = eth_config.target_gas_price; + let pending_create_inherent_data_providers = move |_, ()| async move { + let current = sp_timestamp::InherentDataProvider::from_system_time(); + let next_slot = current.timestamp().as_millis() + slot_duration.as_millis(); + let timestamp = sp_timestamp::InherentDataProvider::new(next_slot.into()); + let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( *timestamp, slot_duration, ); - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((slot, timestamp, dynamic_fee)) - }; - - Box::new(move |deny_unsafe, subscription_task_executor| { - let eth_deps = crate::rpc::EthDeps { - client: client.clone(), - pool: pool.clone(), - graph: pool.pool().clone(), - converter: Some(TransactionConverter), - is_authority, - enable_dev_signer, - network: network.clone(), - sync: sync_service.clone(), - frontier_backend: match frontier_backend.clone() { - fc_db::Backend::KeyValue(b) => Arc::new(b), - fc_db::Backend::Sql(b) => Arc::new(b), - }, - overrides: overrides.clone(), - block_data_cache: block_data_cache.clone(), - filter_pool: filter_pool.clone(), - max_past_logs, - fee_history_cache: fee_history_cache.clone(), - fee_history_cache_limit, - execute_gas_limit_multiplier, - forced_parent_hashes: None, - pending_create_inherent_data_providers, - }; - let deps = crate::rpc::FullDeps { - client: client.clone(), - pool: pool.clone(), - deny_unsafe, - command_sink: if sealing.is_some() { - Some(command_sink.clone()) - } else { - None - }, - eth: eth_deps, - }; - crate::rpc::create_full( - deps, - subscription_task_executor, - pubsub_notification_sinks.clone(), - ) - .map_err(Into::into) - }) - }; - - let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { - config, - client: client.clone(), - backend: backend.clone(), - task_manager: &mut task_manager, - keystore: keystore_container.keystore(), - transaction_pool: transaction_pool.clone(), - rpc_builder, - network: network.clone(), - system_rpc_tx, - tx_handler_controller, - sync_service: sync_service.clone(), - telemetry: telemetry.as_mut(), - })?; - - spawn_frontier_tasks( - &task_manager, - client.clone(), - backend, - frontier_backend, - filter_pool, - overrides, - fee_history_cache, - fee_history_cache_limit, - sync_service.clone(), - pubsub_notification_sinks, - ) - .await; - - if role.is_authority() { - // manual-seal authorship - if let Some(sealing) = sealing { - run_manual_seal_authorship( - ð_config, - sealing, - client, - transaction_pool, - select_chain, - block_import, - &task_manager, - prometheus_registry.as_ref(), - telemetry.as_ref(), - commands_stream, - )?; - - network_starter.start_network(); - log::info!("Manual Seal Ready"); - return Ok(task_manager); - } - - let proposer_factory = sc_basic_authorship::ProposerFactory::new( - task_manager.spawn_handle(), - client.clone(), - transaction_pool.clone(), - prometheus_registry.as_ref(), - telemetry.as_ref().map(|x| x.handle()), - ); - - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let target_gas_price = eth_config.target_gas_price; - let create_inherent_data_providers = move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); + Ok((slot, timestamp, dynamic_fee)) + }; + + Box::new(move |deny_unsafe, subscription_task_executor| { + let eth_deps = crate::rpc::EthDeps { + client: client.clone(), + pool: pool.clone(), + graph: pool.pool().clone(), + converter: Some(TransactionConverter), + is_authority, + enable_dev_signer, + network: network.clone(), + sync: sync_service.clone(), + frontier_backend: match frontier_backend.clone() { + fc_db::Backend::KeyValue(b) => Arc::new(b), + fc_db::Backend::Sql(b) => Arc::new(b), + }, + overrides: overrides.clone(), + block_data_cache: block_data_cache.clone(), + filter_pool: filter_pool.clone(), + max_past_logs, + fee_history_cache: fee_history_cache.clone(), + fee_history_cache_limit, + execute_gas_limit_multiplier, + forced_parent_hashes: None, + pending_create_inherent_data_providers, + }; + let deps = crate::rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + deny_unsafe, + command_sink: if sealing.is_some() { + Some(command_sink.clone()) + } else { + None + }, + eth: eth_deps, + }; + crate::rpc::create_full( + deps, + subscription_task_executor, + pubsub_notification_sinks.clone(), + ) + .map_err(Into::into) + }) + }; + + let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { + config, + client: client.clone(), + backend: backend.clone(), + task_manager: &mut task_manager, + keystore: keystore_container.keystore(), + transaction_pool: transaction_pool.clone(), + rpc_builder, + network: network.clone(), + system_rpc_tx, + tx_handler_controller, + sync_service: sync_service.clone(), + telemetry: telemetry.as_mut(), + })?; + + spawn_frontier_tasks( + &task_manager, + client.clone(), + backend, + frontier_backend, + filter_pool, + overrides, + fee_history_cache, + fee_history_cache_limit, + sync_service.clone(), + pubsub_notification_sinks, + ) + .await; + + if role.is_authority() { + // manual-seal authorship + if let Some(sealing) = sealing { + run_manual_seal_authorship( + ð_config, + sealing, + client, + transaction_pool, + select_chain, + block_import, + &task_manager, + prometheus_registry.as_ref(), + telemetry.as_ref(), + commands_stream, + )?; + + network_starter.start_network(); + log::info!("Manual Seal Ready"); + return Ok(task_manager); + } + + let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool.clone(), + prometheus_registry.as_ref(), + telemetry.as_ref().map(|x| x.handle()), + ); + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + let target_gas_price = eth_config.target_gas_price; + let create_inherent_data_providers = move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( *timestamp, slot_duration, ); - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((slot, timestamp, dynamic_fee)) - }; - - let aura = sc_consensus_aura::start_aura::( - sc_consensus_aura::StartAuraParams { - slot_duration, - client, - select_chain, - block_import, - proposer_factory, - sync_oracle: sync_service.clone(), - justification_sync_link: sync_service.clone(), - create_inherent_data_providers, - force_authoring, - backoff_authoring_blocks: Option::<()>::None, - keystore: keystore_container.keystore(), - block_proposal_slot_portion: sc_consensus_aura::SlotProportion::new(2f32 / 3f32), - max_block_proposal_slot_portion: None, - telemetry: telemetry.as_ref().map(|x| x.handle()), - compatibility_mode: sc_consensus_aura::CompatibilityMode::None, - }, - )?; - // the AURA authoring task is considered essential, i.e. if it - // fails we take down the service with it. - task_manager - .spawn_essential_handle() - .spawn_blocking("aura", Some("block-authoring"), aura); - } - - if enable_grandpa { - // if the node isn't actively participating in consensus then it doesn't - // need a keystore, regardless of which protocol we use below. - let keystore = if role.is_authority() { - Some(keystore_container.keystore()) - } else { - None - }; - - let grandpa_config = sc_consensus_grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_generation_period: GRANDPA_JUSTIFICATION_PERIOD, - name: Some(name), - observer_enabled: false, - keystore, - local_role: role, - telemetry: telemetry.as_ref().map(|x| x.handle()), - protocol_name: grandpa_protocol_name, - }; - - // start the full GRANDPA voter - // NOTE: non-authorities could run the GRANDPA observer protocol, but at - // this point the full voter should provide better guarantees of block - // and vote data availability than the observer. The observer has not - // been tested extensively yet and having most nodes in a network run it - // could lead to finality stalls. - let grandpa_voter = - sc_consensus_grandpa::run_grandpa_voter(sc_consensus_grandpa::GrandpaParams { - config: grandpa_config, - link: grandpa_link, - network, - sync: sync_service, - voting_rule: sc_consensus_grandpa::VotingRulesBuilder::default().build(), - prometheus_registry, - shared_voter_state: sc_consensus_grandpa::SharedVoterState::empty(), - telemetry: telemetry.as_ref().map(|x| x.handle()), - offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool), - })?; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - task_manager - .spawn_essential_handle() - .spawn_blocking("grandpa-voter", None, grandpa_voter); - } - - network_starter.start_network(); - Ok(task_manager) + let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); + Ok((slot, timestamp, dynamic_fee)) + }; + + let aura = sc_consensus_aura::start_aura::( + sc_consensus_aura::StartAuraParams { + slot_duration, + client, + select_chain, + block_import, + proposer_factory, + sync_oracle: sync_service.clone(), + justification_sync_link: sync_service.clone(), + create_inherent_data_providers, + force_authoring, + backoff_authoring_blocks: Option::<()>::None, + keystore: keystore_container.keystore(), + block_proposal_slot_portion: sc_consensus_aura::SlotProportion::new(2f32 / 3f32), + max_block_proposal_slot_portion: None, + telemetry: telemetry.as_ref().map(|x| x.handle()), + compatibility_mode: sc_consensus_aura::CompatibilityMode::None, + }, + )?; + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + task_manager + .spawn_essential_handle() + .spawn_blocking("aura", Some("block-authoring"), aura); + } + + if enable_grandpa { + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = if role.is_authority() { + Some(keystore_container.keystore()) + } else { + None + }; + + let grandpa_config = sc_consensus_grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_generation_period: GRANDPA_JUSTIFICATION_PERIOD, + name: Some(name), + observer_enabled: false, + keystore, + local_role: role, + telemetry: telemetry.as_ref().map(|x| x.handle()), + protocol_name: grandpa_protocol_name, + }; + + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_voter = + sc_consensus_grandpa::run_grandpa_voter(sc_consensus_grandpa::GrandpaParams { + config: grandpa_config, + link: grandpa_link, + network, + sync: sync_service, + voting_rule: sc_consensus_grandpa::VotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state: sc_consensus_grandpa::SharedVoterState::empty(), + telemetry: telemetry.as_ref().map(|x| x.handle()), + offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool), + })?; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + task_manager + .spawn_essential_handle() + .spawn_blocking("grandpa-voter", None, grandpa_voter); + } + + network_starter.start_network(); + Ok(task_manager) } fn run_manual_seal_authorship( - eth_config: &EthConfiguration, - sealing: Sealing, - client: Arc>, - transaction_pool: Arc>>, - select_chain: FullSelectChain, - block_import: BoxBlockImport, - task_manager: &TaskManager, - prometheus_registry: Option<&Registry>, - telemetry: Option<&Telemetry>, - commands_stream: mpsc::Receiver>, + eth_config: &EthConfiguration, + sealing: Sealing, + client: Arc>, + transaction_pool: Arc>>, + select_chain: FullSelectChain, + block_import: BoxBlockImport, + task_manager: &TaskManager, + prometheus_registry: Option<&Registry>, + telemetry: Option<&Telemetry>, + commands_stream: mpsc::Receiver>, ) -> Result<(), ServiceError> where - RuntimeApi: ConstructRuntimeApi>, - RuntimeApi: Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiCollection, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, { - let proposer_factory = sc_basic_authorship::ProposerFactory::new( - task_manager.spawn_handle(), - client.clone(), - transaction_pool.clone(), - prometheus_registry, - telemetry.as_ref().map(|x| x.handle()), - ); - - thread_local!(static TIMESTAMP: RefCell = RefCell::new(0)); - - /// Provide a mock duration starting at 0 in millisecond for timestamp inherent. - /// Each call will increment timestamp by slot_duration making Aura think time has passed. - struct MockTimestampInherentDataProvider; - - #[async_trait::async_trait] - impl sp_inherents::InherentDataProvider for MockTimestampInherentDataProvider { - async fn provide_inherent_data( - &self, - inherent_data: &mut sp_inherents::InherentData, - ) -> Result<(), sp_inherents::Error> { - TIMESTAMP.with(|x| { - *x.borrow_mut() += frontier_template_runtime::SLOT_DURATION; - inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, &*x.borrow()) - }) - } - - async fn try_handle_error( - &self, - _identifier: &sp_inherents::InherentIdentifier, - _error: &[u8], - ) -> Option> { - // The pallet never reports error. - None - } - } - - let target_gas_price = eth_config.target_gas_price; - let create_inherent_data_providers = move |_, ()| async move { - let timestamp = MockTimestampInherentDataProvider; - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((timestamp, dynamic_fee)) - }; - - let manual_seal = match sealing { - Sealing::Manual => future::Either::Left(sc_consensus_manual_seal::run_manual_seal( - sc_consensus_manual_seal::ManualSealParams { - block_import, - env: proposer_factory, - client, - pool: transaction_pool, - commands_stream, - select_chain, - consensus_data_provider: None, - create_inherent_data_providers, - }, - )), - Sealing::Instant => future::Either::Right(sc_consensus_manual_seal::run_instant_seal( - sc_consensus_manual_seal::InstantSealParams { - block_import, - env: proposer_factory, - client, - pool: transaction_pool, - select_chain, - consensus_data_provider: None, - create_inherent_data_providers, - }, - )), - }; - - // we spawn the future on a background thread managed by service. - task_manager - .spawn_essential_handle() - .spawn_blocking("manual-seal", None, manual_seal); - Ok(()) + let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool.clone(), + prometheus_registry, + telemetry.as_ref().map(|x| x.handle()), + ); + + thread_local!(static TIMESTAMP: RefCell = RefCell::new(0)); + + /// Provide a mock duration starting at 0 in millisecond for timestamp inherent. + /// Each call will increment timestamp by slot_duration making Aura think time has passed. + struct MockTimestampInherentDataProvider; + + #[async_trait::async_trait] + impl sp_inherents::InherentDataProvider for MockTimestampInherentDataProvider { + async fn provide_inherent_data( + &self, + inherent_data: &mut sp_inherents::InherentData, + ) -> Result<(), sp_inherents::Error> { + TIMESTAMP.with(|x| { + *x.borrow_mut() += frontier_template_runtime::SLOT_DURATION; + inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, &*x.borrow()) + }) + } + + async fn try_handle_error( + &self, + _identifier: &sp_inherents::InherentIdentifier, + _error: &[u8], + ) -> Option> { + // The pallet never reports error. + None + } + } + + let target_gas_price = eth_config.target_gas_price; + let create_inherent_data_providers = move |_, ()| async move { + let timestamp = MockTimestampInherentDataProvider; + let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); + Ok((timestamp, dynamic_fee)) + }; + + let manual_seal = match sealing { + Sealing::Manual => future::Either::Left(sc_consensus_manual_seal::run_manual_seal( + sc_consensus_manual_seal::ManualSealParams { + block_import, + env: proposer_factory, + client, + pool: transaction_pool, + commands_stream, + select_chain, + consensus_data_provider: None, + create_inherent_data_providers, + }, + )), + Sealing::Instant => future::Either::Right(sc_consensus_manual_seal::run_instant_seal( + sc_consensus_manual_seal::InstantSealParams { + block_import, + env: proposer_factory, + client, + pool: transaction_pool, + select_chain, + consensus_data_provider: None, + create_inherent_data_providers, + }, + )), + }; + + // we spawn the future on a background thread managed by service. + task_manager + .spawn_essential_handle() + .spawn_blocking("manual-seal", None, manual_seal); + Ok(()) } pub async fn build_full( - config: Configuration, - eth_config: EthConfiguration, - sealing: Option, + config: Configuration, + eth_config: EthConfiguration, + sealing: Option, ) -> Result { - new_full::( - config, eth_config, sealing, - ) - .await + new_full::( + config, eth_config, sealing, + ) + .await } pub fn new_chain_ops( - config: &mut Configuration, - eth_config: &EthConfiguration, + config: &mut Configuration, + eth_config: &EthConfiguration, ) -> Result< - ( - Arc, - Arc, - BasicQueue, - TaskManager, - FrontierBackend, - ), - ServiceError, + ( + Arc, + Arc, + BasicQueue, + TaskManager, + FrontierBackend, + ), + ServiceError, > { - config.keystore = sc_service::config::KeystoreConfig::InMemory; - let PartialComponents { - client, - backend, - import_queue, - task_manager, - other, - .. - } = new_partial::( - config, - eth_config, - build_aura_grandpa_import_queue, - )?; - Ok((client, backend, import_queue, task_manager, other.3)) + config.keystore = sc_service::config::KeystoreConfig::InMemory; + let PartialComponents { + client, + backend, + import_queue, + task_manager, + other, + .. + } = new_partial::( + config, + eth_config, + build_aura_grandpa_import_queue, + )?; + Ok((client, backend, import_queue, task_manager, other.3)) } diff --git a/runtime/build.rs b/runtime/build.rs index 90291648..6db3d900 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -1,8 +1,8 @@ fn main() { - #[cfg(feature = "std")] - substrate_wasm_builder::WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() - .build() + #[cfg(feature = "std")] + substrate_wasm_builder::WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .build() } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d905e3d1..2a9da059 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -14,17 +14,17 @@ use scale_codec::{Decode, Encode}; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{ - crypto::{ByteArray, KeyTypeId}, - OpaqueMetadata, H160, H256, U256, + crypto::{ByteArray, KeyTypeId}, + OpaqueMetadata, H160, H256, U256, }; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{ - BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, Get, IdentifyAccount, - IdentityLookup, NumberFor, One, PostDispatchInfoOf, UniqueSaturatedInto, Verify, - }, - transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, - ApplyExtrinsicResult, ConsensusEngineId, Perbill, Permill, + create_runtime_str, generic, impl_opaque_keys, + traits::{ + BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, Get, IdentifyAccount, + IdentityLookup, NumberFor, One, PostDispatchInfoOf, UniqueSaturatedInto, Verify, + }, + transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, + ApplyExtrinsicResult, ConsensusEngineId, Perbill, Permill, }; use sp_std::{marker::PhantomData, prelude::*}; use sp_version::RuntimeVersion; @@ -34,12 +34,12 @@ use frame_support::weights::constants::ParityDbWeight as RuntimeDbWeight; #[cfg(feature = "with-rocksdb-weights")] use frame_support::weights::constants::RocksDbWeight as RuntimeDbWeight; use frame_support::{ - construct_runtime, parameter_types, - traits::{ConstBool, ConstU32, ConstU8, FindAuthor, OnFinalize, OnTimestampSet}, - weights::{constants::WEIGHT_REF_TIME_PER_MILLIS, IdentityFee, Weight}, + construct_runtime, parameter_types, + traits::{ConstBool, ConstU32, ConstU8, FindAuthor, OnFinalize, OnTimestampSet}, + weights::{constants::WEIGHT_REF_TIME_PER_MILLIS, IdentityFee, Weight}, }; use pallet_grandpa::{ - fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, + fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; use pallet_transaction_payment::{ConstFeeMultiplier, CurrencyAdapter}; // Frontier @@ -47,11 +47,11 @@ use fp_account::EthereumSignature; use fp_evm::weight_per_gas; use fp_rpc::TransactionStatus; use pallet_ethereum::{ - Call::transact, PostLogContent, Transaction as EthereumTransaction, TransactionAction, - TransactionData, + Call::transact, PostLogContent, Transaction as EthereumTransaction, TransactionAction, + TransactionData, }; use pallet_evm::{ - Account as EVMAccount, EnsureAccountId20, FeeCalculator, IdentityAddressMapping, Runner, + Account as EVMAccount, EnsureAccountId20, FeeCalculator, IdentityAddressMapping, Runner, }; // A few exports that help ease life for downstream crates. @@ -94,35 +94,35 @@ pub type DigestItem = generic::DigestItem; /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core data structures. pub mod opaque { - use super::*; + use super::*; - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - /// Opaque block header type. - pub type Header = generic::Header; - /// Opaque block type. - pub type Block = generic::Block; - /// Opaque block identifier type. - pub type BlockId = generic::BlockId; + /// Opaque block header type. + pub type Header = generic::Header; + /// Opaque block type. + pub type Block = generic::Block; + /// Opaque block identifier type. + pub type BlockId = generic::BlockId; - impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - pub grandpa: Grandpa, - } - } + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, + } + } } #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("frontier-template"), - impl_name: create_runtime_str!("frontier-template"), - authoring_version: 1, - spec_version: 1, - impl_version: 1, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 1, + spec_name: create_runtime_str!("frontier-template"), + impl_name: create_runtime_str!("frontier-template"), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, }; pub const MILLISECS_PER_BLOCK: u64 = 6000; @@ -137,309 +137,309 @@ pub const DAYS: BlockNumber = HOURS * 24; /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> sp_version::NativeVersion { - sp_version::NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } + sp_version::NativeVersion { + runtime_version: VERSION, + can_author_with: Default::default(), + } } const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); /// We allow for 2000ms of compute with a 6 second average block time. pub const WEIGHT_MILLISECS_PER_BLOCK: u64 = 2000; pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( - WEIGHT_MILLISECS_PER_BLOCK * WEIGHT_REF_TIME_PER_MILLIS, - u64::MAX, + WEIGHT_MILLISECS_PER_BLOCK * WEIGHT_REF_TIME_PER_MILLIS, + u64::MAX, ); pub const MAXIMUM_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; parameter_types! { - pub const Version: RuntimeVersion = VERSION; - pub const BlockHashCount: BlockNumber = 256; - pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights - ::with_sensible_defaults(MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO); - pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength - ::max_with_normal_ratio(MAXIMUM_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); - pub const SS58Prefix: u8 = 42; + pub const Version: RuntimeVersion = VERSION; + pub const BlockHashCount: BlockNumber = 256; + pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights + ::with_sensible_defaults(MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO); + pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength + ::max_with_normal_ratio(MAXIMUM_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); + pub const SS58Prefix: u8 = 42; } // Configure FRAME pallets to include in runtime. impl frame_system::Config for Runtime { - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = frame_support::traits::Everything; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = BlockWeights; - /// The maximum length of a block (in bytes). - type BlockLength = BlockLength; - /// The ubiquitous origin type. - type RuntimeOrigin = RuntimeOrigin; - /// The aggregated dispatch type that is available for extrinsics. - type RuntimeCall = RuntimeCall; - /// The index type for storing how many extrinsics an account has signed. - type Nonce = Nonce; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = IdentityLookup; - /// The block type. - type Block = Block; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RuntimeDbWeight; - /// Version of the runtime. - type Version = Version; - /// Converts a module to the index of the module in `construct_runtime!`. - /// - /// This type is being generated by `construct_runtime!`. - type PalletInfo = PalletInfo; - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = (); - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// The set code logic, just the default since we're not a parachain. - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = frame_support::traits::Everything; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = BlockWeights; + /// The maximum length of a block (in bytes). + type BlockLength = BlockLength; + /// The ubiquitous origin type. + type RuntimeOrigin = RuntimeOrigin; + /// The aggregated dispatch type that is available for extrinsics. + type RuntimeCall = RuntimeCall; + /// The index type for storing how many extrinsics an account has signed. + type Nonce = Nonce; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = IdentityLookup; + /// The block type. + type Block = Block; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RuntimeDbWeight; + /// Version of the runtime. + type Version = Version; + /// Converts a module to the index of the module in `construct_runtime!`. + /// + /// This type is being generated by `construct_runtime!`. + type PalletInfo = PalletInfo; + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = (); + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// The set code logic, just the default since we're not a parachain. + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { - pub const MaxAuthorities: u32 = 100; + pub const MaxAuthorities: u32 = 100; } impl pallet_aura::Config for Runtime { - type AuthorityId = AuraId; - type MaxAuthorities = MaxAuthorities; - type DisabledValidators = (); - type AllowMultipleBlocksPerSlot = ConstBool; + type AuthorityId = AuraId; + type MaxAuthorities = MaxAuthorities; + type DisabledValidators = (); + type AllowMultipleBlocksPerSlot = ConstBool; } impl pallet_grandpa::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); - type MaxAuthorities = ConstU32<32>; - type MaxNominators = ConstU32<0>; - type MaxSetIdSessionEntries = (); - type KeyOwnerProof = sp_core::Void; - type EquivocationReportSystem = (); + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type MaxAuthorities = ConstU32<32>; + type MaxNominators = ConstU32<0>; + type MaxSetIdSessionEntries = (); + type KeyOwnerProof = sp_core::Void; + type EquivocationReportSystem = (); } parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; - pub storage EnableManualSeal: bool = false; + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; + pub storage EnableManualSeal: bool = false; } pub struct ConsensusOnTimestampSet(PhantomData); impl OnTimestampSet for ConsensusOnTimestampSet { - fn on_timestamp_set(moment: T::Moment) { - if EnableManualSeal::get() { - return; - } - as OnTimestampSet>::on_timestamp_set(moment) - } + fn on_timestamp_set(moment: T::Moment) { + if EnableManualSeal::get() { + return; + } + as OnTimestampSet>::on_timestamp_set(moment) + } } impl pallet_timestamp::Config for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = ConsensusOnTimestampSet; - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = ConsensusOnTimestampSet; + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } parameter_types! { - pub const ExistentialDeposit: u128 = 500; - // For weight estimation, we assume that the most locks on an individual account will be 50. - // This number may need to be adjusted in the future if this assumption no longer holds true. - pub const MaxLocks: u32 = 50; + pub const ExistentialDeposit: u128 = 500; + // For weight estimation, we assume that the most locks on an individual account will be 50. + // This number may need to be adjusted in the future if this assumption no longer holds true. + pub const MaxLocks: u32 = 50; } impl pallet_balances::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = pallet_balances::weights::SubstrateWeight; - type Balance = Balance; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type ReserveIdentifier = [u8; 8]; - type RuntimeHoldReason = (); - type FreezeIdentifier = (); - type MaxLocks = MaxLocks; - type MaxReserves = (); - type MaxHolds = (); - type MaxFreezes = (); + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type Balance = Balance; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = (); + type FreezeIdentifier = (); + type MaxLocks = MaxLocks; + type MaxReserves = (); + type MaxHolds = (); + type MaxFreezes = (); } parameter_types! { - pub FeeMultiplier: Multiplier = Multiplier::one(); + pub FeeMultiplier: Multiplier = Multiplier::one(); } impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = CurrencyAdapter; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = IdentityFee; - type FeeMultiplierUpdate = ConstFeeMultiplier; + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = IdentityFee; + type FeeMultiplierUpdate = ConstFeeMultiplier; } impl pallet_sudo::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type WeightInfo = pallet_sudo::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type WeightInfo = pallet_sudo::weights::SubstrateWeight; } impl pallet_evm_chain_id::Config for Runtime {} pub struct FindAuthorTruncated(PhantomData); impl> FindAuthor for FindAuthorTruncated { - fn find_author<'a, I>(digests: I) -> Option - where - I: 'a + IntoIterator, - { - if let Some(author_index) = F::find_author(digests) { - let authority_id = Aura::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); - } - None - } + fn find_author<'a, I>(digests: I) -> Option + where + I: 'a + IntoIterator, + { + if let Some(author_index) = F::find_author(digests) { + let authority_id = Aura::authorities()[author_index as usize].clone(); + return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); + } + None + } } const BLOCK_GAS_LIMIT: u64 = 75_000_000; const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; parameter_types! { - pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); - pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); - pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); - pub WeightPerGas: Weight = Weight::from_parts(weight_per_gas(BLOCK_GAS_LIMIT, NORMAL_DISPATCH_RATIO, WEIGHT_MILLISECS_PER_BLOCK), 0); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); + pub WeightPerGas: Weight = Weight::from_parts(weight_per_gas(BLOCK_GAS_LIMIT, NORMAL_DISPATCH_RATIO, WEIGHT_MILLISECS_PER_BLOCK), 0); } impl pallet_evm::Config for Runtime { - type FeeCalculator = BaseFee; - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type WeightPerGas = WeightPerGas; - type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; - type CallOrigin = EnsureAccountId20; - type WithdrawOrigin = EnsureAccountId20; - type AddressMapping = IdentityAddressMapping; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type PrecompilesType = FrontierPrecompiles; - type PrecompilesValue = PrecompilesValue; - type ChainId = EVMChainId; - type BlockGasLimit = BlockGasLimit; - type Runner = pallet_evm::runner::stack::Runner; - type OnChargeTransaction = (); - type OnCreate = (); - type FindAuthor = FindAuthorTruncated; - type GasLimitPovSizeRatio = GasLimitPovSizeRatio; - type Timestamp = Timestamp; - type WeightInfo = pallet_evm::weights::SubstrateWeight; + type FeeCalculator = BaseFee; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAccountId20; + type WithdrawOrigin = EnsureAccountId20; + type AddressMapping = IdentityAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = FrontierPrecompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = EVMChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = (); + type OnCreate = (); + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = pallet_evm::weights::SubstrateWeight; } parameter_types! { - pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; } impl pallet_ethereum::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type StateRoot = pallet_ethereum::IntermediateStateRoot; - type PostLogContent = PostBlockAndTxnHashes; - type ExtraDataLength = ConstU32<30>; + type RuntimeEvent = RuntimeEvent; + type StateRoot = pallet_ethereum::IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; } parameter_types! { - pub BoundDivision: U256 = U256::from(1024); + pub BoundDivision: U256 = U256::from(1024); } impl pallet_dynamic_fee::Config for Runtime { - type MinGasPriceBoundDivisor = BoundDivision; + type MinGasPriceBoundDivisor = BoundDivision; } parameter_types! { - pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000); - pub DefaultElasticity: Permill = Permill::from_parts(125_000); + pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000); + pub DefaultElasticity: Permill = Permill::from_parts(125_000); } pub struct BaseFeeThreshold; impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold { - fn lower() -> Permill { - Permill::zero() - } - fn ideal() -> Permill { - Permill::from_parts(500_000) - } - fn upper() -> Permill { - Permill::from_parts(1_000_000) - } + fn lower() -> Permill { + Permill::zero() + } + fn ideal() -> Permill { + Permill::from_parts(500_000) + } + fn upper() -> Permill { + Permill::from_parts(1_000_000) + } } impl pallet_base_fee::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Threshold = BaseFeeThreshold; - type DefaultBaseFeePerGas = DefaultBaseFeePerGas; - type DefaultElasticity = DefaultElasticity; + type RuntimeEvent = RuntimeEvent; + type Threshold = BaseFeeThreshold; + type DefaultBaseFeePerGas = DefaultBaseFeePerGas; + type DefaultElasticity = DefaultElasticity; } impl pallet_hotfix_sufficients::Config for Runtime { - type AddressMapping = IdentityAddressMapping; - type WeightInfo = pallet_hotfix_sufficients::weights::SubstrateWeight; + type AddressMapping = IdentityAddressMapping; + type WeightInfo = pallet_hotfix_sufficients::weights::SubstrateWeight; } // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub enum Runtime { - System: frame_system, - Timestamp: pallet_timestamp, - Aura: pallet_aura, - Grandpa: pallet_grandpa, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - Sudo: pallet_sudo, - Ethereum: pallet_ethereum, - EVM: pallet_evm, - EVMChainId: pallet_evm_chain_id, - DynamicFee: pallet_dynamic_fee, - BaseFee: pallet_base_fee, - HotfixSufficients: pallet_hotfix_sufficients, - } + pub enum Runtime { + System: frame_system, + Timestamp: pallet_timestamp, + Aura: pallet_aura, + Grandpa: pallet_grandpa, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, + Sudo: pallet_sudo, + Ethereum: pallet_ethereum, + EVM: pallet_evm, + EVMChainId: pallet_evm_chain_id, + DynamicFee: pallet_dynamic_fee, + BaseFee: pallet_base_fee, + HotfixSufficients: pallet_hotfix_sufficients, + } ); #[derive(Clone)] pub struct TransactionConverter; impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { - UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } } impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction( - &self, - transaction: pallet_ethereum::Transaction, - ) -> opaque::UncheckedExtrinsic { - let extrinsic = UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ); - let encoded = extrinsic.encode(); - opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) - .expect("Encoded extrinsic is always valid") - } + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } } /// The address format for describing accounts. @@ -454,88 +454,88 @@ pub type SignedBlock = generic::SignedBlock; pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - fp_self_contained::UncheckedExtrinsic; + fp_self_contained::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = - fp_self_contained::CheckedExtrinsic; + fp_self_contained::CheckedExtrinsic; /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, >; impl fp_self_contained::SelfContainedCall for RuntimeCall { - type SignedInfo = H160; - - fn is_self_contained(&self) -> bool { - match self { - RuntimeCall::Ethereum(call) => call.is_self_contained(), - _ => false, - } - } - - fn check_self_contained(&self) -> Option> { - match self { - RuntimeCall::Ethereum(call) => call.check_self_contained(), - _ => None, - } - } - - fn validate_self_contained( - &self, - info: &Self::SignedInfo, - dispatch_info: &DispatchInfoOf, - len: usize, - ) -> Option { - match self { - RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), - _ => None, - } - } - - fn pre_dispatch_self_contained( - &self, - info: &Self::SignedInfo, - dispatch_info: &DispatchInfoOf, - len: usize, - ) -> Option> { - match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - } - _ => None, - } - } - - fn apply_self_contained( - self, - info: Self::SignedInfo, - ) -> Option>> { - match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from( - pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))) - } - _ => None, - } - } + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + } + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from( + pallet_ethereum::RawOrigin::EthereumTransaction(info), + ))) + } + _ => None, + } + } } #[cfg(feature = "runtime-benchmarks")] @@ -544,418 +544,418 @@ extern crate frame_benchmarking; #[cfg(feature = "runtime-benchmarks")] mod benches { - define_benchmarks!( - [frame_benchmarking, BaselineBench::] - [frame_system, SystemBench::] - [pallet_balances, Balances] - [pallet_timestamp, Timestamp] - [pallet_sudo, Sudo] - [pallet_evm, EVM] - ); + define_benchmarks!( + [frame_benchmarking, BaselineBench::] + [frame_system, SystemBench::] + [pallet_balances, Balances] + [pallet_timestamp, Timestamp] + [pallet_sudo, Sudo] + [pallet_evm, EVM] + ); } impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - - fn metadata_at_version(version: u32) -> Option { - Runtime::metadata_at_version(version) - } - - fn metadata_versions() -> Vec { - Runtime::metadata_versions() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) - } - - fn authorities() -> Vec { - Aura::authorities().to_vec() - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Nonce { - System::account_nonce(account) - } - } - - impl fp_rpc::EthereumRuntimeRPCApi for Runtime { - fn chain_id() -> u64 { - ::ChainId::get() - } - - fn account_basic(address: H160) -> EVMAccount { - let (account, _) = pallet_evm::Pallet::::account_basic(&address); - account - } - - fn gas_price() -> U256 { - let (gas_price, _) = ::FeeCalculator::min_gas_price(); - gas_price - } - - fn account_code_at(address: H160) -> Vec { - pallet_evm::AccountCodes::::get(address) - } - - fn author() -> H160 { - >::find_author() - } - - fn storage_at(address: H160, index: U256) -> H256 { - let mut tmp = [0u8; 32]; - index.to_big_endian(&mut tmp); - pallet_evm::AccountStorages::::get(address, H256::from_slice(&tmp[..])) - } - - fn call( - from: H160, - to: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - - let gas_limit = gas_limit.min(u64::MAX.into()); - let transaction_data = TransactionData::new( - TransactionAction::Call(to), - data.clone(), - nonce.unwrap_or_default(), - gas_limit, - None, - max_fee_per_gas, - max_priority_fee_per_gas, - value, - Some(::ChainId::get()), - access_list.clone().unwrap_or_default(), - ); - let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); - - ::Runner::call( - from, - to, - data, - value, - gas_limit.unique_saturated_into(), - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - false, - true, - weight_limit, - proof_size_base_cost, - config.as_ref().unwrap_or(::config()), - ).map_err(|err| err.error.into()) - } - - fn create( - from: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - - let transaction_data = TransactionData::new( - TransactionAction::Create, - data.clone(), - nonce.unwrap_or_default(), - gas_limit, - None, - max_fee_per_gas, - max_priority_fee_per_gas, - value, - Some(::ChainId::get()), - access_list.clone().unwrap_or_default(), - ); - let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); - - ::Runner::create( - from, - data, - value, - gas_limit.unique_saturated_into(), - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - false, - true, - weight_limit, - proof_size_base_cost, - config.as_ref().unwrap_or(::config()), - ).map_err(|err| err.error.into()) - } - - fn current_transaction_statuses() -> Option> { - pallet_ethereum::CurrentTransactionStatuses::::get() - } - - fn current_block() -> Option { - pallet_ethereum::CurrentBlock::::get() - } - - fn current_receipts() -> Option> { - pallet_ethereum::CurrentReceipts::::get() - } - - fn current_all() -> ( - Option, - Option>, - Option> - ) { - ( - pallet_ethereum::CurrentBlock::::get(), - pallet_ethereum::CurrentReceipts::::get(), - pallet_ethereum::CurrentTransactionStatuses::::get() - ) - } - - fn extrinsic_filter( - xts: Vec<::Extrinsic>, - ) -> Vec { - xts.into_iter().filter_map(|xt| match xt.0.function { - RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), - _ => None - }).collect::>() - } - - fn elasticity() -> Option { - Some(pallet_base_fee::Elasticity::::get()) - } - - fn gas_limit_multiplier_support() {} - - fn pending_block( - xts: Vec<::Extrinsic>, - ) -> (Option, Option>) { - for ext in xts.into_iter() { - let _ = Executive::apply_extrinsic(ext); - } - - Ethereum::on_finalize(System::block_number() + 1); - - ( - pallet_ethereum::CurrentBlock::::get(), - pallet_ethereum::CurrentTransactionStatuses::::get() - ) - } - } - - impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { - fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { - UncheckedExtrinsic::new_unsigned( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< - Block, - Balance, - > for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32 - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - opaque::SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - opaque::SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_authorities() -> GrandpaAuthorityList { - Grandpa::grandpa_authorities() - } - - fn current_set_id() -> fg_primitives::SetId { - Grandpa::current_set_id() - } - - fn submit_report_equivocation_unsigned_extrinsic( - _equivocation_proof: fg_primitives::EquivocationProof< - ::Hash, - NumberFor, - >, - _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, - ) -> Option<()> { - None - } - - fn generate_key_ownership_proof( - _set_id: fg_primitives::SetId, - _authority_id: GrandpaId, - ) -> Option { - // NOTE: this is the only implementation possible since we've - // defined our key owner proof type as a bottom type (i.e. a type - // with no values). - None - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - - use baseline::Pallet as BaselineBench; - use frame_system_benchmarking::Pallet as SystemBench; - use pallet_hotfix_sufficients::Pallet as PalletHotfixSufficients; - - let mut list = Vec::::new(); - list_benchmarks!(list, extra); - list_benchmark!(list, extra, pallet_hotfix_sufficients, PalletHotfixSufficients::); - - let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, add_benchmark}; - use frame_support::traits::TrackedStorageKey; - - use pallet_evm::Pallet as PalletEvmBench; - use pallet_hotfix_sufficients::Pallet as PalletHotfixSufficientsBench; - - impl baseline::Config for Runtime {} - impl frame_system_benchmarking::Config for Runtime {} - - let whitelist: Vec = vec![]; - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - - add_benchmark!(params, batches, pallet_evm, PalletEvmBench::); - add_benchmark!(params, batches, pallet_hotfix_sufficients, PalletHotfixSufficientsBench::); - - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok(batches) - } - } + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> Vec { + Runtime::metadata_versions() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + Aura::authorities().to_vec() + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl fp_rpc::EthereumRuntimeRPCApi for Runtime { + fn chain_id() -> u64 { + ::ChainId::get() + } + + fn account_basic(address: H160) -> EVMAccount { + let (account, _) = pallet_evm::Pallet::::account_basic(&address); + account + } + + fn gas_price() -> U256 { + let (gas_price, _) = ::FeeCalculator::min_gas_price(); + gas_price + } + + fn account_code_at(address: H160) -> Vec { + pallet_evm::AccountCodes::::get(address) + } + + fn author() -> H160 { + >::find_author() + } + + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + pallet_evm::AccountStorages::::get(address, H256::from_slice(&tmp[..])) + } + + fn call( + from: H160, + to: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let gas_limit = gas_limit.min(u64::MAX.into()); + let transaction_data = TransactionData::new( + TransactionAction::Call(to), + data.clone(), + nonce.unwrap_or_default(), + gas_limit, + None, + max_fee_per_gas, + max_priority_fee_per_gas, + value, + Some(::ChainId::get()), + access_list.clone().unwrap_or_default(), + ); + let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); + + ::Runner::call( + from, + to, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + false, + true, + weight_limit, + proof_size_base_cost, + config.as_ref().unwrap_or(::config()), + ).map_err(|err| err.error.into()) + } + + fn create( + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let transaction_data = TransactionData::new( + TransactionAction::Create, + data.clone(), + nonce.unwrap_or_default(), + gas_limit, + None, + max_fee_per_gas, + max_priority_fee_per_gas, + value, + Some(::ChainId::get()), + access_list.clone().unwrap_or_default(), + ); + let (weight_limit, proof_size_base_cost) = pallet_ethereum::Pallet::::transaction_weight(&transaction_data); + + ::Runner::create( + from, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + false, + true, + weight_limit, + proof_size_base_cost, + config.as_ref().unwrap_or(::config()), + ).map_err(|err| err.error.into()) + } + + fn current_transaction_statuses() -> Option> { + pallet_ethereum::CurrentTransactionStatuses::::get() + } + + fn current_block() -> Option { + pallet_ethereum::CurrentBlock::::get() + } + + fn current_receipts() -> Option> { + pallet_ethereum::CurrentReceipts::::get() + } + + fn current_all() -> ( + Option, + Option>, + Option> + ) { + ( + pallet_ethereum::CurrentBlock::::get(), + pallet_ethereum::CurrentReceipts::::get(), + pallet_ethereum::CurrentTransactionStatuses::::get() + ) + } + + fn extrinsic_filter( + xts: Vec<::Extrinsic>, + ) -> Vec { + xts.into_iter().filter_map(|xt| match xt.0.function { + RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), + _ => None + }).collect::>() + } + + fn elasticity() -> Option { + Some(pallet_base_fee::Elasticity::::get()) + } + + fn gas_limit_multiplier_support() {} + + fn pending_block( + xts: Vec<::Extrinsic>, + ) -> (Option, Option>) { + for ext in xts.into_iter() { + let _ = Executive::apply_extrinsic(ext); + } + + Ethereum::on_finalize(System::block_number() + 1); + + ( + pallet_ethereum::CurrentBlock::::get(), + pallet_ethereum::CurrentTransactionStatuses::::get() + ) + } + } + + impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { + fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< + Block, + Balance, + > for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32 + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + opaque::SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> GrandpaAuthorityList { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + NumberFor, + >, + _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + _authority_id: GrandpaId, + ) -> Option { + // NOTE: this is the only implementation possible since we've + // defined our key owner proof type as a bottom type (i.e. a type + // with no values). + None + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use baseline::Pallet as BaselineBench; + use frame_system_benchmarking::Pallet as SystemBench; + use pallet_hotfix_sufficients::Pallet as PalletHotfixSufficients; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + list_benchmark!(list, extra, pallet_hotfix_sufficients, PalletHotfixSufficients::); + + let storage_info = AllPalletsWithSystem::storage_info(); + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, add_benchmark}; + use frame_support::traits::TrackedStorageKey; + + use pallet_evm::Pallet as PalletEvmBench; + use pallet_hotfix_sufficients::Pallet as PalletHotfixSufficientsBench; + + impl baseline::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime {} + + let whitelist: Vec = vec![]; + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmark!(params, batches, pallet_evm, PalletEvmBench::); + add_benchmark!(params, batches, pallet_hotfix_sufficients, PalletHotfixSufficientsBench::); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } } #[cfg(test)] mod tests { - use super::{Runtime, WeightPerGas}; - #[test] - fn configured_base_extrinsic_weight_is_evm_compatible() { - let min_ethereum_transaction_weight = WeightPerGas::get() * 21_000; - let base_extrinsic = ::BlockWeights::get() - .get(frame_support::dispatch::DispatchClass::Normal) - .base_extrinsic; - assert!(base_extrinsic.ref_time() <= min_ethereum_transaction_weight.ref_time()); - } + use super::{Runtime, WeightPerGas}; + #[test] + fn configured_base_extrinsic_weight_is_evm_compatible() { + let min_ethereum_transaction_weight = WeightPerGas::get() * 21_000; + let base_extrinsic = ::BlockWeights::get() + .get(frame_support::dispatch::DispatchClass::Normal) + .base_extrinsic; + assert!(base_extrinsic.ref_time() <= min_ethereum_transaction_weight.ref_time()); + } } diff --git a/runtime/src/precompiles.rs b/runtime/src/precompiles.rs index c563f8e1..dda53350 100644 --- a/runtime/src/precompiles.rs +++ b/runtime/src/precompiles.rs @@ -1,5 +1,5 @@ use pallet_evm::{ - IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, + IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, }; use sp_core::H160; use sp_std::marker::PhantomData; @@ -12,50 +12,50 @@ pub struct FrontierPrecompiles(PhantomData); impl FrontierPrecompiles where - R: pallet_evm::Config, + R: pallet_evm::Config, { - pub fn new() -> Self { - Self(Default::default()) - } - pub fn used_addresses() -> [H160; 7] { - [ - hash(1), - hash(2), - hash(3), - hash(4), - hash(5), - hash(1024), - hash(1025), - ] - } + pub fn new() -> Self { + Self(Default::default()) + } + pub fn used_addresses() -> [H160; 7] { + [ + hash(1), + hash(2), + hash(3), + hash(4), + hash(5), + hash(1024), + hash(1025), + ] + } } impl PrecompileSet for FrontierPrecompiles where - R: pallet_evm::Config, + R: pallet_evm::Config, { - fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - match handle.code_address() { - // Ethereum precompiles : - a if a == hash(1) => Some(ECRecover::execute(handle)), - a if a == hash(2) => Some(Sha256::execute(handle)), - a if a == hash(3) => Some(Ripemd160::execute(handle)), - a if a == hash(4) => Some(Identity::execute(handle)), - a if a == hash(5) => Some(Modexp::execute(handle)), - // Non-Frontier specific nor Ethereum precompiles : - a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), - a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), - _ => None, - } - } + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + match handle.code_address() { + // Ethereum precompiles : + a if a == hash(1) => Some(ECRecover::execute(handle)), + a if a == hash(2) => Some(Sha256::execute(handle)), + a if a == hash(3) => Some(Ripemd160::execute(handle)), + a if a == hash(4) => Some(Identity::execute(handle)), + a if a == hash(5) => Some(Modexp::execute(handle)), + // Non-Frontier specific nor Ethereum precompiles : + a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), + a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), + _ => None, + } + } - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), - extra_cost: 0, - } - } + fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { + IsPrecompileResult::Answer { + is_precompile: Self::used_addresses().contains(&address), + extra_cost: 0, + } + } } fn hash(a: u64) -> H160 { - H160::from_low_u64_be(a) + H160::from_low_u64_be(a) }