diff --git a/Cargo.lock b/Cargo.lock index 58e2d61a6e6e4109473151a8223dc81bb0c4d4fe..d5970f50481a6e295f0dbfb04ba7c962c1d0874b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1289,6 +1289,7 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-finality-grandpa", + "sp-keyring", "sp-membership", "sp-offchain", "sp-runtime", diff --git a/Cargo.toml b/Cargo.toml index 49847c10744cb1ba9abce0d04b67ffbcbc49ab7e..8730f7bd23b9cd2b83e6b95f9d3e9f996da78eb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,7 +65,7 @@ sc-cli = { git = "https://github.com/librelois/substrate.git", branch = "duniter sc-client-api = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sc-consensus = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } babe = { package = "sc-consensus-babe", git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } -sc-consensus-manual-seal = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } +manual-seal = { package = "sc-consensus-manual-seal", git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sc-consensus-uncles = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sc-executor = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sc-finality-grandpa = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } @@ -84,6 +84,7 @@ sp-consensus-babe = { git = "https://github.com/librelois/substrate.git", branch sp-core = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sp-finality-grandpa = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sp-offchain = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } +sp-keyring = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sp-runtime = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sp-session = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } sp-storage = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-01" } diff --git a/node/src/chain_spec/gtest.rs b/node/src/chain_spec/gtest.rs index 79c21b10fa427faf6f7e36135c28d4e1578359e3..40f17388058ab667527807e70ee394b196c145a6 100644 --- a/node/src/chain_spec/gtest.rs +++ b/node/src/chain_spec/gtest.rs @@ -57,6 +57,53 @@ pub fn get_authority_keys_from_seed(s: &str) -> AuthorityKeys { ) } +pub fn development_chain_spec() -> Result<ChainSpec, String> { + let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; + + Ok(ChainSpec::from_genesis( + // Name + "Äžtest Development", + // ID + "gtest_dev", + ChainType::Development, + move || { + devnet_genesis( + wasm_binary, + // Initial authorities + vec![get_authority_keys_from_seed("Alice")], + // Inital identities + btreemap![ + IdtyName::from("Alice") => get_account_id_from_seed::<sr25519::Public>("Alice"), + IdtyName::from("Bob") => get_account_id_from_seed::<sr25519::Public>("Bob"), + IdtyName::from("Charlie") => get_account_id_from_seed::<sr25519::Public>("Charlie"), + ], + // Sudo account + get_account_id_from_seed::<sr25519::Public>("Alice"), + true, + ) + }, + // Bootnodes + vec![], + // Telemetry + None, + // Protocol ID + None, + // Properties + Some( + serde_json::json!({ + "tokenDecimals": TOKEN_DECIMALS, + "tokenSymbol": TOKEN_SYMBOL, + }) + .as_object() + .expect("must be a map") + .clone(), + ), + // Extensions + None, + )) +} + + fn devnet_genesis( wasm_binary: &[u8], initial_authorities: Vec<AuthorityKeys>, @@ -71,7 +118,6 @@ fn devnet_genesis( }, authority_discovery: Default::default(), balances: BalancesConfig { - // Configure endowed accounts with initial balance of INITIAL_BALANCE. balances: Vec::with_capacity(0), }, babe: BabeConfig { @@ -139,52 +185,6 @@ fn devnet_genesis( } } -pub fn development_chain_spec() -> Result<ChainSpec, String> { - let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; - - Ok(ChainSpec::from_genesis( - // Name - "Äžtest Development", - // ID - "gtest_dev", - ChainType::Development, - move || { - devnet_genesis( - wasm_binary, - // Initial PoA authorities - vec![get_authority_keys_from_seed("Alice")], - // Inital identities - btreemap![ - IdtyName::from("Alice") => get_account_id_from_seed::<sr25519::Public>("Alice"), - IdtyName::from("Bob") => get_account_id_from_seed::<sr25519::Public>("Bob"), - IdtyName::from("Charlie") => get_account_id_from_seed::<sr25519::Public>("Charlie"), - ], - // Sudo account - get_account_id_from_seed::<sr25519::Public>("Alice"), - true, - ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - None, - // Properties - Some( - serde_json::json!({ - "tokenDecimals": TOKEN_DECIMALS, - "tokenSymbol": TOKEN_SYMBOL, - }) - .as_object() - .expect("must be a map") - .clone(), - ), - // Extensions - None, - )) -} - pub fn local_testnet_config(authorities_count: usize) -> Result<ChainSpec, String> { let wasm_binary = WASM_BINARY.ok_or_else(|| "wasm not available".to_string())?; diff --git a/node/src/command.rs b/node/src/command.rs index bfa0271c69b5689e468dee3c35bdfc946228b25a..6e3c3534a1ec99b1fb10a37f636c8aa0d5c1354a 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -215,22 +215,29 @@ pub fn run() -> sc_cli::Result<()> { None => { let runner = cli.create_runner(&cli.run)?; runner.run_node_until_exit(|config| async move { + let chain_spec_id = config.chain_spec.id(); + let sealing_opt = if chain_spec_id.ends_with("dev") && chain_spec_id != "gdev" { + Some(cli.sealing) + } else { + None + }; match config.chain_spec.runtime_type() { #[cfg(feature = "g1")] RuntimeType::G1 => { - service::new_full::<g1_runtime::RuntimeApi, G1Executor>(config, None) + service::new_full::<g1_runtime::RuntimeApi, G1Executor>(config, sealing_opt) .map_err(sc_cli::Error::Service) } #[cfg(feature = "gtest")] - RuntimeType::GTest => { - service::new_full::<gtest_runtime::RuntimeApi, GTestExecutor>(config, None) - .map_err(sc_cli::Error::Service) - } + RuntimeType::GTest => service::new_full::< + gtest_runtime::RuntimeApi, + GTestExecutor, + >(config, sealing_opt) + .map_err(sc_cli::Error::Service), #[cfg(feature = "gdev")] RuntimeType::GDev => { service::new_full::<gdev_runtime::RuntimeApi, GDevExecutor>( config, - Some(cli.sealing), + sealing_opt, ) .map_err(sc_cli::Error::Service) } diff --git a/node/src/rpc.rs b/node/src/rpc.rs index 4a64fb4b851c1f4e94c5ab94756f11ca0e9e2ec0..f831299c31b638d687f0582887fd8dd694afed61 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -25,7 +25,7 @@ pub use sc_rpc_api::DenyUnsafe; use common_runtime::Block; use common_runtime::{AccountId, Balance, Index}; -use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApi}; +use manual_seal::rpc::{ManualSeal, ManualSealApi}; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; @@ -41,9 +41,8 @@ pub struct FullDeps<C, P> { /// Whether to deny unsafe calls pub deny_unsafe: DenyUnsafe, /// Manual seal command sink - pub command_sink_opt: Option< - futures::channel::mpsc::Sender<sc_consensus_manual_seal::EngineCommand<sp_core::H256>>, - >, + pub command_sink_opt: + Option<futures::channel::mpsc::Sender<manual_seal::EngineCommand<sp_core::H256>>>, } /// Instantiate all full RPC extensions. diff --git a/node/src/service.rs b/node/src/service.rs index a0b30a00116fd112278cb44d6839b1b44f9eff5d..42fda611c0de31f00461d0803261521d49befe86 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -22,8 +22,8 @@ use self::client::{Client, RuntimeApiCollection}; use async_io::Timer; use common_runtime::Block; use futures::{Stream, StreamExt}; +use manual_seal::{run_manual_seal, EngineCommand, ManualSealParams}; use sc_client_api::ExecutorProvider; -use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams}; pub use sc_executor::NativeElseWasmExecutor; use sc_finality_grandpa::SharedVoterState; use sc_keystore::LocalKeystore; @@ -212,15 +212,12 @@ pub fn new_partial<RuntimeApi, Executor>( sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, Executor>>, sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, Executor>>, ( - Option<( - babe::BabeBlockImport< - Block, - FullClient<RuntimeApi, Executor>, - FullGrandpaBlockImport<RuntimeApi, Executor>, - >, - babe::BabeLink<Block>, - )>, - FullGrandpaBlockImport<RuntimeApi, Executor>, + babe::BabeBlockImport< + Block, + FullClient<RuntimeApi, Executor>, + FullGrandpaBlockImport<RuntimeApi, Executor>, + >, + babe::BabeLink<Block>, sc_finality_grandpa::LinkHalf<Block, FullClient<RuntimeApi, Executor>, FullSelectChain>, Option<Telemetry>, ), @@ -294,45 +291,40 @@ where let justification_import = grandpa_block_import.clone(); - let (babe_setup_opt, import_queue) = if consensus_manual { - ( - None, - sc_consensus_manual_seal::import_queue( - Box::new(grandpa_block_import.clone()), - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - ), + let babe_config = babe::Config::get(&*client)?; + let (babe_block_import, babe_link) = + babe::block_import(babe_config, grandpa_block_import.clone(), client.clone())?; + + let import_queue = if consensus_manual { + manual_seal::import_queue( + Box::new(babe_block_import.clone()), + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), ) } else { - let babe_config = babe::Config::get(&*client)?; - let (babe_block_import, babe_link) = - babe::block_import(babe_config, grandpa_block_import.clone(), client.clone())?; let slot_duration = babe_link.config().slot_duration(); - ( - Some((babe_block_import.clone(), babe_link.clone())), - babe::import_queue( - babe_link, - babe_block_import, - Some(Box::new(justification_import)), - client.clone(), - select_chain.clone(), - move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = + babe::import_queue( + babe_link.clone(), + babe_block_import.clone(), + Some(Box::new(justification_import)), + client.clone(), + select_chain.clone(), + move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration( *timestamp, slot_duration, ); - Ok((timestamp, slot)) - }, - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), - telemetry.as_ref().map(|x| x.handle()), - )?, - ) + Ok((timestamp, slot)) + }, + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), + telemetry.as_ref().map(|x| x.handle()), + )? }; Ok(sc_service::PartialComponents { @@ -343,12 +335,7 @@ where keystore_container, select_chain, transaction_pool, - other: ( - babe_setup_opt, - grandpa_block_import, - grandpa_link, - telemetry, - ), + other: (babe_block_import, babe_link, grandpa_link, telemetry), }) } @@ -381,7 +368,7 @@ where mut keystore_container, select_chain, transaction_pool, - other: (babe_setup_opt, block_import, grandpa_link, mut telemetry), + other: (block_import, babe_link, grandpa_link, mut telemetry), } = new_partial::<RuntimeApi, Executor>(&config, sealing_opt.is_some())?; if let Some(url) = &config.keystore_remote { @@ -478,8 +465,23 @@ where )), }; + let babe_consensus_data_provider = + manual_seal::consensus::babe::BabeConsensusDataProvider::new( + client.clone(), + keystore_container.sync_keystore(), + babe_link.epoch_changes().clone(), + vec![( + sp_consensus_babe::AuthorityId::from( + sp_keyring::sr25519::Keyring::Alice.public(), + ), + 1000, + )], + ) + .expect("failed to create BabeConsensusDataProvider"); + + let client_clone = client.clone(); task_manager.spawn_essential_handle().spawn_blocking( - "authorship_task", + "manual-seal", Some("block-authoring"), run_manual_seal(ManualSealParams { block_import, @@ -488,11 +490,24 @@ where pool: transaction_pool.clone(), commands_stream, select_chain, - consensus_data_provider: None, - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + consensus_data_provider: Some(Box::new(babe_consensus_data_provider)), + create_inherent_data_providers: move |_, _| { + let client = client_clone.clone(); + async move { + let timestamp = + manual_seal::consensus::babe::SlotTimestampProvider::new( + client.clone(), + ) + .map_err(|err| format!("{:?}", err))?; + let babe = sp_consensus_babe::inherents::InherentDataProvider::new( + timestamp.slot().into(), + ); + Ok((timestamp, babe)) + } + }, }), ); - } else if let Some((babe_block_import, babe_link)) = babe_setup_opt { + } else { let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); @@ -502,7 +517,7 @@ where keystore: keystore_container.sync_keystore(), client: client.clone(), select_chain, - block_import: babe_block_import, + block_import, env: proposer_factory, sync_oracle: network.clone(), justification_sync_link: network.clone(), @@ -518,10 +533,10 @@ where let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let slot = - sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration( - *timestamp, - slot_duration, - ); + sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration( + *timestamp, + slot_duration, + ); Ok((timestamp, slot, uncles)) } @@ -543,8 +558,6 @@ where Some("block-authoring"), babe, ); - } else { - panic!("We must have babe or manual seal") } }