Skip to main content

anvil_polkadot/substrate_node/service/
client.rs

1use crate::substrate_node::{
2    genesis::DevelopmentGenesisBlockBuilder,
3    service::{
4        Backend,
5        backend::StorageOverrides,
6        executor::{Executor, WasmExecutor},
7    },
8};
9use parking_lot::Mutex;
10use polkadot_sdk::{
11    parachains_common::opaque::Block,
12    sc_chain_spec::get_extension,
13    sc_client_api::{BadBlocks, ForkBlocks, execution_extensions::ExecutionExtensions},
14    sc_service::{self, KeystoreContainer, LocalCallExecutor, TaskManager, new_db_backend},
15    sp_keystore::KeystorePtr,
16};
17use std::{collections::HashMap, sync::Arc};
18use substrate_runtime::RuntimeApi;
19
20pub type Client = sc_service::client::Client<Backend, Executor, Block, RuntimeApi>;
21
22pub fn new_client(
23    genesis_block_number: u64,
24    config: &sc_service::Configuration,
25    executor: WasmExecutor,
26    storage_overrides: Arc<Mutex<StorageOverrides>>,
27) -> Result<(Arc<Client>, Arc<Backend>, KeystorePtr, TaskManager), sc_service::error::Error> {
28    let backend = new_db_backend(config.db_config())?;
29
30    let genesis_block_builder = DevelopmentGenesisBlockBuilder::new(
31        genesis_block_number,
32        config.chain_spec.as_storage_builder(),
33        !config.no_genesis(),
34        backend.clone(),
35        executor.clone(),
36    )?;
37
38    let keystore_container = KeystoreContainer::new(&config.keystore)?;
39
40    let task_manager = {
41        let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry);
42        TaskManager::new(config.tokio_handle.clone(), registry)?
43    };
44
45    let chain_spec = &config.chain_spec;
46    let fork_blocks =
47        get_extension::<ForkBlocks<Block>>(chain_spec.extensions()).cloned().unwrap_or_default();
48
49    let bad_blocks =
50        get_extension::<BadBlocks<Block>>(chain_spec.extensions()).cloned().unwrap_or_default();
51
52    let execution_extensions = ExecutionExtensions::new(None, Arc::new(executor.clone()));
53
54    let wasm_runtime_substitutes = HashMap::new();
55
56    let client = {
57        let client_config = sc_service::ClientConfig {
58            offchain_worker_enabled: config.offchain_worker.enabled,
59            offchain_indexing_api: config.offchain_worker.indexing_enabled,
60            wasm_runtime_overrides: config.wasm_runtime_overrides.clone(),
61            no_genesis: config.no_genesis(),
62            wasm_runtime_substitutes,
63            enable_import_proof_recording: false,
64        };
65        let inner_executor = LocalCallExecutor::new(
66            backend.clone(),
67            executor,
68            client_config.clone(),
69            execution_extensions,
70        )?;
71        let executor = Executor::new(inner_executor, storage_overrides, backend.clone());
72
73        Client::new(
74            backend.clone(),
75            executor,
76            Box::new(task_manager.spawn_handle()),
77            genesis_block_builder,
78            fork_blocks,
79            bad_blocks,
80            None,
81            None,
82            client_config,
83        )?
84    };
85
86    Ok((Arc::new(client), backend, keystore_container.keystore(), task_manager))
87}