service.rs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. // Copyright 2019 Joystream Contributors
  2. // This file is part of Joystream node.
  3. // Joystream node is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. // Joystream node is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with Joystream node. If not, see <http://www.gnu.org/licenses/>.
  13. #![warn(unused_extern_crates)]
  14. // Substrate implementation issue.
  15. #![allow(clippy::redundant_closure_call)]
  16. // Substrate implementation issue.
  17. #![allow(clippy::type_complexity)]
  18. //! Service implementation. Specialized wrapper over substrate service.
  19. use crate::node_executor;
  20. use crate::node_rpc;
  21. use node_runtime::opaque::Block;
  22. use node_runtime::RuntimeApi;
  23. use futures::prelude::*;
  24. use node_executor::Executor;
  25. use sc_client_api::{ExecutorProvider, RemoteBackend};
  26. use sc_finality_grandpa as grandpa;
  27. use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
  28. use sc_network::{Event, NetworkService};
  29. use sc_service::{
  30. config::{Configuration, Role},
  31. error::Error as ServiceError,
  32. RpcHandlers, TaskManager,
  33. };
  34. use sp_core::traits::BareCryptoStorePtr;
  35. use sp_inherents::InherentDataProviders;
  36. use sp_runtime::traits::Block as BlockT;
  37. use std::sync::Arc;
  38. type FullClient = sc_service::TFullClient<Block, RuntimeApi, Executor>;
  39. type FullBackend = sc_service::TFullBackend<Block>;
  40. type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
  41. type FullGrandpaBlockImport =
  42. grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>;
  43. type LightClient = sc_service::TLightClient<Block, RuntimeApi, Executor>;
  44. pub fn new_partial(
  45. config: &Configuration,
  46. ) -> Result<
  47. sc_service::PartialComponents<
  48. FullClient,
  49. FullBackend,
  50. FullSelectChain,
  51. sp_consensus::DefaultImportQueue<Block, FullClient>,
  52. sc_transaction_pool::FullPool<Block, FullClient>,
  53. (
  54. impl Fn(node_rpc::DenyUnsafe, sc_rpc::SubscriptionTaskExecutor) -> node_rpc::IoHandler,
  55. (
  56. sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
  57. grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
  58. sc_consensus_babe::BabeLink<Block>,
  59. ),
  60. (
  61. grandpa::SharedVoterState,
  62. Arc<GrandpaFinalityProofProvider<FullBackend, Block>>,
  63. ),
  64. ),
  65. >,
  66. ServiceError,
  67. > {
  68. let (client, backend, keystore, task_manager) =
  69. sc_service::new_full_parts::<Block, RuntimeApi, Executor>(&config)?;
  70. let client = Arc::new(client);
  71. let select_chain = sc_consensus::LongestChain::new(backend.clone());
  72. let transaction_pool = sc_transaction_pool::BasicPool::new_full(
  73. config.transaction_pool.clone(),
  74. config.prometheus_registry(),
  75. task_manager.spawn_handle(),
  76. client.clone(),
  77. );
  78. let (grandpa_block_import, grandpa_link) = grandpa::block_import(
  79. client.clone(),
  80. &(client.clone() as Arc<_>),
  81. select_chain.clone(),
  82. )?;
  83. let justification_import = grandpa_block_import.clone();
  84. let (block_import, babe_link) = sc_consensus_babe::block_import(
  85. sc_consensus_babe::Config::get_or_compute(&*client)?,
  86. grandpa_block_import,
  87. client.clone(),
  88. )?;
  89. let inherent_data_providers = sp_inherents::InherentDataProviders::new();
  90. let import_queue = sc_consensus_babe::import_queue(
  91. babe_link.clone(),
  92. block_import.clone(),
  93. Some(Box::new(justification_import)),
  94. None,
  95. client.clone(),
  96. select_chain.clone(),
  97. inherent_data_providers.clone(),
  98. &task_manager.spawn_handle(),
  99. config.prometheus_registry(),
  100. sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
  101. )?;
  102. let import_setup = (block_import, grandpa_link, babe_link);
  103. let (rpc_extensions_builder, rpc_setup) = {
  104. let (_, grandpa_link, babe_link) = &import_setup;
  105. let justification_stream = grandpa_link.justification_stream();
  106. let shared_authority_set = grandpa_link.shared_authority_set().clone();
  107. let shared_voter_state = grandpa::SharedVoterState::empty();
  108. let finality_proof_provider =
  109. GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
  110. let rpc_setup = (shared_voter_state.clone(), finality_proof_provider.clone());
  111. let babe_config = babe_link.config().clone();
  112. let shared_epoch_changes = babe_link.epoch_changes().clone();
  113. let client = client.clone();
  114. let pool = transaction_pool.clone();
  115. let select_chain = select_chain.clone();
  116. let keystore = keystore.clone();
  117. let rpc_extensions_builder = move |deny_unsafe, subscription_executor| {
  118. let deps = node_rpc::FullDeps {
  119. client: client.clone(),
  120. pool: pool.clone(),
  121. select_chain: select_chain.clone(),
  122. deny_unsafe,
  123. babe: node_rpc::BabeDeps {
  124. babe_config: babe_config.clone(),
  125. shared_epoch_changes: shared_epoch_changes.clone(),
  126. keystore: keystore.clone(),
  127. },
  128. grandpa: node_rpc::GrandpaDeps {
  129. shared_voter_state: shared_voter_state.clone(),
  130. shared_authority_set: shared_authority_set.clone(),
  131. justification_stream: justification_stream.clone(),
  132. subscription_executor,
  133. finality_provider: finality_proof_provider.clone(),
  134. },
  135. };
  136. node_rpc::create_full(deps)
  137. };
  138. (rpc_extensions_builder, rpc_setup)
  139. };
  140. Ok(sc_service::PartialComponents {
  141. client,
  142. backend,
  143. task_manager,
  144. keystore,
  145. select_chain,
  146. import_queue,
  147. transaction_pool,
  148. inherent_data_providers,
  149. other: (rpc_extensions_builder, import_setup, rpc_setup),
  150. })
  151. }
  152. pub struct NewFullBase {
  153. pub task_manager: TaskManager,
  154. pub inherent_data_providers: InherentDataProviders,
  155. pub client: Arc<FullClient>,
  156. pub network: Arc<NetworkService<Block, <Block as BlockT>::Hash>>,
  157. pub network_status_sinks: sc_service::NetworkStatusSinks<Block>,
  158. pub transaction_pool: Arc<sc_transaction_pool::FullPool<Block, FullClient>>,
  159. }
  160. /// Creates a full service from the configuration.
  161. pub fn new_full_base(
  162. config: Configuration,
  163. with_startup_data: impl FnOnce(
  164. &sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
  165. &sc_consensus_babe::BabeLink<Block>,
  166. ),
  167. ) -> Result<NewFullBase, ServiceError> {
  168. let sc_service::PartialComponents {
  169. client,
  170. backend,
  171. mut task_manager,
  172. import_queue,
  173. keystore,
  174. select_chain,
  175. transaction_pool,
  176. inherent_data_providers,
  177. other: (rpc_extensions_builder, import_setup, rpc_setup),
  178. } = new_partial(&config)?;
  179. let (shared_voter_state, finality_proof_provider) = rpc_setup;
  180. let (network, network_status_sinks, system_rpc_tx, network_starter) =
  181. sc_service::build_network(sc_service::BuildNetworkParams {
  182. config: &config,
  183. client: client.clone(),
  184. transaction_pool: transaction_pool.clone(),
  185. spawn_handle: task_manager.spawn_handle(),
  186. import_queue,
  187. on_demand: None,
  188. block_announce_validator_builder: None,
  189. finality_proof_request_builder: None,
  190. finality_proof_provider: Some(finality_proof_provider),
  191. })?;
  192. if config.offchain_worker.enabled {
  193. sc_service::build_offchain_workers(
  194. &config,
  195. backend.clone(),
  196. task_manager.spawn_handle(),
  197. client.clone(),
  198. network.clone(),
  199. );
  200. }
  201. let role = config.role.clone();
  202. let force_authoring = config.force_authoring;
  203. let name = config.network.node_name.clone();
  204. let enable_grandpa = !config.disable_grandpa;
  205. let prometheus_registry = config.prometheus_registry().cloned();
  206. let telemetry_connection_sinks = sc_service::TelemetryConnectionSinks::default();
  207. sc_service::spawn_tasks(sc_service::SpawnTasksParams {
  208. config,
  209. backend,
  210. client: client.clone(),
  211. keystore: keystore.clone(),
  212. network: network.clone(),
  213. rpc_extensions_builder: Box::new(rpc_extensions_builder),
  214. transaction_pool: transaction_pool.clone(),
  215. task_manager: &mut task_manager,
  216. on_demand: None,
  217. remote_blockchain: None,
  218. telemetry_connection_sinks: telemetry_connection_sinks.clone(),
  219. network_status_sinks: network_status_sinks.clone(),
  220. system_rpc_tx,
  221. })?;
  222. let (block_import, grandpa_link, babe_link) = import_setup;
  223. (with_startup_data)(&block_import, &babe_link);
  224. if let sc_service::config::Role::Authority { .. } = &role {
  225. let proposer = sc_basic_authorship::ProposerFactory::new(
  226. client.clone(),
  227. transaction_pool.clone(),
  228. prometheus_registry.as_ref(),
  229. );
  230. let can_author_with =
  231. sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
  232. let babe_config = sc_consensus_babe::BabeParams {
  233. keystore: keystore.clone(),
  234. client: client.clone(),
  235. select_chain,
  236. env: proposer,
  237. block_import,
  238. sync_oracle: network.clone(),
  239. inherent_data_providers: inherent_data_providers.clone(),
  240. force_authoring,
  241. babe_link,
  242. can_author_with,
  243. };
  244. let babe = sc_consensus_babe::start_babe(babe_config)?;
  245. task_manager
  246. .spawn_essential_handle()
  247. .spawn_blocking("babe-proposer", babe);
  248. }
  249. // Spawn authority discovery module.
  250. if matches!(role, Role::Authority { .. } | Role::Sentry { .. }) {
  251. let (sentries, authority_discovery_role) = match role {
  252. sc_service::config::Role::Authority { ref sentry_nodes } => (
  253. sentry_nodes.clone(),
  254. sc_authority_discovery::Role::Authority(keystore.clone()),
  255. ),
  256. sc_service::config::Role::Sentry { .. } => {
  257. (vec![], sc_authority_discovery::Role::Sentry)
  258. }
  259. _ => unreachable!("Due to outer matches! constraint; qed."),
  260. };
  261. let dht_event_stream = network
  262. .event_stream("authority-discovery")
  263. .filter_map(|e| async move {
  264. match e {
  265. Event::Dht(e) => Some(e),
  266. _ => None,
  267. }
  268. })
  269. .boxed();
  270. let (authority_discovery_worker, _service) = sc_authority_discovery::new_worker_and_service(
  271. client.clone(),
  272. network.clone(),
  273. sentries,
  274. dht_event_stream,
  275. authority_discovery_role,
  276. prometheus_registry.clone(),
  277. );
  278. task_manager
  279. .spawn_handle()
  280. .spawn("authority-discovery-worker", authority_discovery_worker);
  281. }
  282. // if the node isn't actively participating in consensus then it doesn't
  283. // need a keystore, regardless of which protocol we use below.
  284. let keystore = if role.is_authority() {
  285. Some(keystore as BareCryptoStorePtr)
  286. } else {
  287. None
  288. };
  289. let config = grandpa::Config {
  290. // FIXME #1578 make this available through chainspec
  291. gossip_duration: std::time::Duration::from_millis(333),
  292. justification_period: 512,
  293. name: Some(name),
  294. observer_enabled: false,
  295. keystore,
  296. is_authority: role.is_network_authority(),
  297. };
  298. if enable_grandpa {
  299. // start the full GRANDPA voter
  300. // NOTE: non-authorities could run the GRANDPA observer protocol, but at
  301. // this point the full voter should provide better guarantees of block
  302. // and vote data availability than the observer. The observer has not
  303. // been tested extensively yet and having most nodes in a network run it
  304. // could lead to finality stalls.
  305. let grandpa_config = grandpa::GrandpaParams {
  306. config,
  307. link: grandpa_link,
  308. network: network.clone(),
  309. inherent_data_providers: inherent_data_providers.clone(),
  310. telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()),
  311. voting_rule: grandpa::VotingRulesBuilder::default().build(),
  312. prometheus_registry,
  313. shared_voter_state,
  314. };
  315. // the GRANDPA voter task is considered infallible, i.e.
  316. // if it fails we take down the service with it.
  317. task_manager
  318. .spawn_essential_handle()
  319. .spawn_blocking("grandpa-voter", grandpa::run_grandpa_voter(grandpa_config)?);
  320. } else {
  321. grandpa::setup_disabled_grandpa(client.clone(), &inherent_data_providers, network.clone())?;
  322. }
  323. network_starter.start_network();
  324. Ok(NewFullBase {
  325. task_manager,
  326. inherent_data_providers,
  327. client,
  328. network,
  329. network_status_sinks,
  330. transaction_pool,
  331. })
  332. }
  333. /// Builds a new service for a full client.
  334. pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
  335. new_full_base(config, |_, _| ()).map(|NewFullBase { task_manager, .. }| task_manager)
  336. }
  337. // Substrate implementation issue.
  338. #[allow(clippy::type_complexity)]
  339. pub fn new_light_base(
  340. config: Configuration,
  341. ) -> Result<
  342. (
  343. TaskManager,
  344. RpcHandlers,
  345. Arc<LightClient>,
  346. Arc<NetworkService<Block, <Block as BlockT>::Hash>>,
  347. Arc<
  348. sc_transaction_pool::LightPool<Block, LightClient, sc_network::config::OnDemand<Block>>,
  349. >,
  350. ),
  351. ServiceError,
  352. > {
  353. let (client, backend, keystore, mut task_manager, on_demand) =
  354. sc_service::new_light_parts::<Block, RuntimeApi, Executor>(&config)?;
  355. let select_chain = sc_consensus::LongestChain::new(backend.clone());
  356. let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(
  357. config.transaction_pool.clone(),
  358. config.prometheus_registry(),
  359. task_manager.spawn_handle(),
  360. client.clone(),
  361. on_demand.clone(),
  362. ));
  363. let grandpa_block_import = grandpa::light_block_import(
  364. client.clone(),
  365. backend.clone(),
  366. &(client.clone() as Arc<_>),
  367. Arc::new(on_demand.checker().clone()),
  368. )?;
  369. let finality_proof_import = grandpa_block_import.clone();
  370. let finality_proof_request_builder =
  371. finality_proof_import.create_finality_proof_request_builder();
  372. let (babe_block_import, babe_link) = sc_consensus_babe::block_import(
  373. sc_consensus_babe::Config::get_or_compute(&*client)?,
  374. grandpa_block_import,
  375. client.clone(),
  376. )?;
  377. let inherent_data_providers = sp_inherents::InherentDataProviders::new();
  378. let import_queue = sc_consensus_babe::import_queue(
  379. babe_link,
  380. babe_block_import,
  381. None,
  382. Some(Box::new(finality_proof_import)),
  383. client.clone(),
  384. select_chain,
  385. inherent_data_providers,
  386. &task_manager.spawn_handle(),
  387. config.prometheus_registry(),
  388. sp_consensus::NeverCanAuthor,
  389. )?;
  390. let finality_proof_provider =
  391. GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
  392. let (network, network_status_sinks, system_rpc_tx, network_starter) =
  393. sc_service::build_network(sc_service::BuildNetworkParams {
  394. config: &config,
  395. client: client.clone(),
  396. transaction_pool: transaction_pool.clone(),
  397. spawn_handle: task_manager.spawn_handle(),
  398. import_queue,
  399. on_demand: Some(on_demand.clone()),
  400. block_announce_validator_builder: None,
  401. finality_proof_request_builder: Some(finality_proof_request_builder),
  402. finality_proof_provider: Some(finality_proof_provider),
  403. })?;
  404. network_starter.start_network();
  405. if config.offchain_worker.enabled {
  406. sc_service::build_offchain_workers(
  407. &config,
  408. backend.clone(),
  409. task_manager.spawn_handle(),
  410. client.clone(),
  411. network.clone(),
  412. );
  413. }
  414. let light_deps = node_rpc::LightDeps {
  415. remote_blockchain: backend.remote_blockchain(),
  416. fetcher: on_demand.clone(),
  417. client: client.clone(),
  418. pool: transaction_pool.clone(),
  419. };
  420. let rpc_extensions = node_rpc::create_light(light_deps);
  421. let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
  422. on_demand: Some(on_demand),
  423. remote_blockchain: Some(backend.remote_blockchain()),
  424. rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)),
  425. client: client.clone(),
  426. transaction_pool: transaction_pool.clone(),
  427. config,
  428. keystore,
  429. backend,
  430. network_status_sinks,
  431. system_rpc_tx,
  432. network: network.clone(),
  433. telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(),
  434. task_manager: &mut task_manager,
  435. })?;
  436. Ok((
  437. task_manager,
  438. rpc_handlers,
  439. client,
  440. network,
  441. transaction_pool,
  442. ))
  443. }
  444. /// Builds a new service for a light client.
  445. pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {
  446. new_light_base(config).map(|(task_manager, _, _, _, _)| task_manager)
  447. }
  448. #[cfg(test)]
  449. mod tests {
  450. use crate::service::{new_full_base, new_light_base, NewFullBase};
  451. use codec::Encode;
  452. use node_runtime::opaque::Block;
  453. use node_runtime::{currency::CENTS, SLOT_DURATION};
  454. use node_runtime::{Address, BalancesCall, Call, UncheckedExtrinsic};
  455. use node_runtime::{DigestItem, Signature};
  456. use sc_client_api::BlockBackend;
  457. use sc_consensus_babe::{BabeIntermediate, CompatibleDigestItem, INTERMEDIATE_KEY};
  458. use sc_consensus_epochs::descendent_query;
  459. use sc_service_test::TestNetNode;
  460. use sp_consensus::{
  461. BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
  462. RecordProof,
  463. };
  464. use sp_core::{crypto::Pair as CryptoPair, H256};
  465. use sp_finality_tracker;
  466. use sp_keyring::AccountKeyring;
  467. use sp_runtime::traits::IdentifyAccount;
  468. use sp_runtime::{
  469. generic::{BlockId, Digest, Era, SignedPayload},
  470. traits::Verify,
  471. traits::{Block as BlockT, Header as HeaderT},
  472. };
  473. use sp_timestamp;
  474. use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool};
  475. use std::{any::Any, borrow::Cow, sync::Arc};
  476. type AccountPublic = <Signature as Verify>::Signer;
  477. #[test]
  478. // It is "ignored", but the node-cli ignored tests are running on the CI.
  479. // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`.
  480. #[ignore]
  481. fn test_sync() {
  482. let keystore_path = tempfile::tempdir().expect("Creates keystore path");
  483. let keystore =
  484. sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore");
  485. let alice = keystore
  486. .write()
  487. .insert_ephemeral_from_seed::<sc_consensus_babe::AuthorityPair>("//Alice")
  488. .expect("Creates authority pair");
  489. let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
  490. // For the block factory
  491. let mut slot_num = 1u64;
  492. // For the extrinsics factory
  493. let bob = Arc::new(AccountKeyring::Bob.pair());
  494. let charlie = Arc::new(AccountKeyring::Charlie.pair());
  495. let mut index = 0;
  496. sc_service_test::sync(
  497. chain_spec,
  498. |config| {
  499. let mut setup_handles = None;
  500. let NewFullBase {
  501. task_manager,
  502. inherent_data_providers,
  503. client,
  504. network,
  505. transaction_pool,
  506. ..
  507. } = new_full_base(
  508. config,
  509. |block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
  510. babe_link: &sc_consensus_babe::BabeLink<Block>| {
  511. setup_handles = Some((block_import.clone(), babe_link.clone()));
  512. },
  513. )?;
  514. let node = sc_service_test::TestNetComponents::new(
  515. task_manager,
  516. client,
  517. network,
  518. transaction_pool,
  519. );
  520. Ok((node, (inherent_data_providers, setup_handles.unwrap())))
  521. },
  522. |config| {
  523. let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?;
  524. Ok(sc_service_test::TestNetComponents::new(
  525. keep_alive,
  526. client,
  527. network,
  528. transaction_pool,
  529. ))
  530. },
  531. |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| {
  532. let mut inherent_data = inherent_data_providers
  533. .create_inherent_data()
  534. .expect("Creates inherent data.");
  535. inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64);
  536. let parent_id = BlockId::number(service.client().chain_info().best_number);
  537. let parent_header = service.client().header(&parent_id).unwrap().unwrap();
  538. let parent_hash = parent_header.hash();
  539. let parent_number = *parent_header.number();
  540. futures::executor::block_on(service.transaction_pool().maintain(
  541. ChainEvent::NewBestBlock {
  542. hash: parent_header.hash(),
  543. tree_route: None,
  544. },
  545. ));
  546. let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
  547. service.client(),
  548. service.transaction_pool(),
  549. None,
  550. );
  551. let epoch_descriptor = babe_link
  552. .epoch_changes()
  553. .lock()
  554. .epoch_descriptor_for_child_of(
  555. descendent_query(&*service.client()),
  556. &parent_hash,
  557. parent_number,
  558. slot_num,
  559. )
  560. .unwrap()
  561. .unwrap();
  562. let mut digest = Digest::<H256>::default();
  563. // even though there's only one authority some slots might be empty,
  564. // so we must keep trying the next slots until we can claim one.
  565. let babe_pre_digest = loop {
  566. inherent_data.replace_data(
  567. sp_timestamp::INHERENT_IDENTIFIER,
  568. &(slot_num * SLOT_DURATION),
  569. );
  570. if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
  571. slot_num,
  572. &parent_header,
  573. &*service.client(),
  574. &keystore,
  575. &babe_link,
  576. ) {
  577. break babe_pre_digest;
  578. }
  579. slot_num += 1;
  580. };
  581. digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(
  582. babe_pre_digest,
  583. ));
  584. let new_block = futures::executor::block_on(async move {
  585. let proposer = proposer_factory.init(&parent_header).await;
  586. proposer
  587. .unwrap()
  588. .propose(
  589. inherent_data,
  590. digest,
  591. std::time::Duration::from_secs(1),
  592. RecordProof::Yes,
  593. )
  594. .await
  595. })
  596. .expect("Error making test block")
  597. .block;
  598. let (new_header, new_body) = new_block.deconstruct();
  599. let pre_hash = new_header.hash();
  600. // sign the pre-sealed hash of the block and then
  601. // add it to a digest item.
  602. let to_sign = pre_hash.encode();
  603. let signature = alice.sign(&to_sign[..]);
  604. let item = <DigestItem as CompatibleDigestItem>::babe_seal(signature.into());
  605. slot_num += 1;
  606. let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
  607. params.post_digests.push(item);
  608. params.body = Some(new_body);
  609. params.intermediates.insert(
  610. Cow::from(INTERMEDIATE_KEY),
  611. Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
  612. );
  613. params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
  614. block_import
  615. .import_block(params, Default::default())
  616. .expect("error importing test block");
  617. },
  618. |service, _| {
  619. let amount = 5 * CENTS;
  620. let to: Address = AccountPublic::from(bob.public()).into_account().into();
  621. let from: Address = AccountPublic::from(charlie.public()).into_account().into();
  622. let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
  623. let best_block_id = BlockId::number(service.client().chain_info().best_number);
  624. let (spec_version, transaction_version) = {
  625. let version = service.client().runtime_version_at(&best_block_id).unwrap();
  626. (version.spec_version, version.transaction_version)
  627. };
  628. let signer = charlie.clone();
  629. let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
  630. let check_spec_version = frame_system::CheckSpecVersion::new();
  631. let check_tx_version = frame_system::CheckTxVersion::new();
  632. let check_genesis = frame_system::CheckGenesis::new();
  633. let check_era = frame_system::CheckEra::from(Era::Immortal);
  634. let check_nonce = frame_system::CheckNonce::from(index);
  635. let check_weight = frame_system::CheckWeight::new();
  636. let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0);
  637. let extra = (
  638. check_spec_version,
  639. check_tx_version,
  640. check_genesis,
  641. check_era,
  642. check_nonce,
  643. check_weight,
  644. payment,
  645. );
  646. let raw_payload = SignedPayload::from_raw(
  647. function,
  648. extra,
  649. (
  650. spec_version,
  651. transaction_version,
  652. genesis_hash,
  653. genesis_hash,
  654. (),
  655. (),
  656. (),
  657. ),
  658. );
  659. let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
  660. let (function, extra, _) = raw_payload.deconstruct();
  661. index += 1;
  662. UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
  663. .into()
  664. },
  665. );
  666. }
  667. #[test]
  668. #[ignore]
  669. fn test_consensus() {
  670. sc_service_test::consensus(
  671. crate::chain_spec::tests::integration_test_config_with_two_authorities(),
  672. |config| {
  673. let NewFullBase {
  674. task_manager,
  675. client,
  676. network,
  677. transaction_pool,
  678. ..
  679. } = new_full_base(config, |_, _| ())?;
  680. Ok(sc_service_test::TestNetComponents::new(
  681. task_manager,
  682. client,
  683. network,
  684. transaction_pool,
  685. ))
  686. },
  687. |config| {
  688. let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?;
  689. Ok(sc_service_test::TestNetComponents::new(
  690. keep_alive,
  691. client,
  692. network,
  693. transaction_pool,
  694. ))
  695. },
  696. vec!["//Alice".into(), "//Bob".into()],
  697. )
  698. }
  699. }