mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 02:57:57 +00:00
Support custom genesis block (#12291)
* Set genesis block data using the built genesis block * Make resolve_state_version_from_wasm a separate function and some small refactorings Useful for the commit following. * Introduce trait BuildGenesisBlock Substrate users can use this trait to implement their custom genesis block when constructing the client. * Make call_executor test compile * cargo +nightly fmt --all * Fix test * Remove unnecessary clone * FMT * Apply review suggestions * Revert changes to new_full_client() and new_full_parts() signature * Remove needless `Block` type in `resolve_state_version_from_wasm`
This commit is contained in:
@@ -397,24 +397,34 @@ impl BenchDb {
|
||||
let task_executor = TaskExecutor::new();
|
||||
|
||||
let backend = sc_service::new_db_backend(db_config).expect("Should not fail");
|
||||
let executor = NativeElseWasmExecutor::new(
|
||||
WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: WasmtimeInstantiationStrategy::PoolingCopyOnWrite,
|
||||
},
|
||||
None,
|
||||
8,
|
||||
2,
|
||||
);
|
||||
let client_config = sc_service::ClientConfig::default();
|
||||
let genesis_block_builder = sc_service::GenesisBlockBuilder::new(
|
||||
&keyring.generate_genesis(),
|
||||
!client_config.no_genesis,
|
||||
backend.clone(),
|
||||
executor.clone(),
|
||||
)
|
||||
.expect("Failed to create genesis block builder");
|
||||
|
||||
let client = sc_service::new_client(
|
||||
backend.clone(),
|
||||
NativeElseWasmExecutor::new(
|
||||
WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: WasmtimeInstantiationStrategy::PoolingCopyOnWrite,
|
||||
},
|
||||
None,
|
||||
8,
|
||||
2,
|
||||
),
|
||||
&keyring.generate_genesis(),
|
||||
executor,
|
||||
genesis_block_builder,
|
||||
None,
|
||||
None,
|
||||
ExecutionExtensions::new(profile.into_execution_strategies(), None, None),
|
||||
Box::new(task_executor.clone()),
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
client_config,
|
||||
)
|
||||
.expect("Should not fail");
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ use crate::{
|
||||
config::{Configuration, KeystoreConfig, PrometheusConfig},
|
||||
error::Error,
|
||||
metrics::MetricsService,
|
||||
start_rpc_servers, RpcHandlers, SpawnTaskHandle, TaskManager, TransactionPoolAdapter,
|
||||
start_rpc_servers, BuildGenesisBlock, GenesisBlockBuilder, RpcHandlers, SpawnTaskHandle,
|
||||
TaskManager, TransactionPoolAdapter,
|
||||
};
|
||||
use futures::{channel::oneshot, future::ready, FutureExt, StreamExt};
|
||||
use jsonrpsee::RpcModule;
|
||||
@@ -72,7 +73,6 @@ use sp_keystore::{CryptoStore, SyncCryptoStore, SyncCryptoStorePtr};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, BlockIdTo, NumberFor, Zero},
|
||||
BuildStorage,
|
||||
};
|
||||
use std::{str::FromStr, sync::Arc, time::SystemTime};
|
||||
|
||||
@@ -182,7 +182,7 @@ where
|
||||
new_full_parts(config, telemetry, executor).map(|parts| parts.0)
|
||||
}
|
||||
|
||||
/// Create the initial parts of a full node.
|
||||
/// Create the initial parts of a full node with the default genesis block builder.
|
||||
pub fn new_full_parts<TBl, TRtApi, TExec>(
|
||||
config: &Configuration,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
@@ -191,6 +191,34 @@ pub fn new_full_parts<TBl, TRtApi, TExec>(
|
||||
where
|
||||
TBl: BlockT,
|
||||
TExec: CodeExecutor + RuntimeVersionOf + Clone,
|
||||
{
|
||||
let backend = new_db_backend(config.db_config())?;
|
||||
|
||||
let genesis_block_builder = GenesisBlockBuilder::new(
|
||||
config.chain_spec.as_storage_builder(),
|
||||
!config.no_genesis(),
|
||||
backend.clone(),
|
||||
executor.clone(),
|
||||
)?;
|
||||
|
||||
new_full_parts_with_genesis_builder(config, telemetry, executor, backend, genesis_block_builder)
|
||||
}
|
||||
|
||||
/// Create the initial parts of a full node.
|
||||
pub fn new_full_parts_with_genesis_builder<TBl, TRtApi, TExec, TBuildGenesisBlock>(
|
||||
config: &Configuration,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
executor: TExec,
|
||||
backend: Arc<TFullBackend<TBl>>,
|
||||
genesis_block_builder: TBuildGenesisBlock,
|
||||
) -> Result<TFullParts<TBl, TRtApi, TExec>, Error>
|
||||
where
|
||||
TBl: BlockT,
|
||||
TExec: CodeExecutor + RuntimeVersionOf + Clone,
|
||||
TBuildGenesisBlock: BuildGenesisBlock<
|
||||
TBl,
|
||||
BlockImportOperation = <Backend<TBl> as sc_client_api::backend::Backend<TBl>>::BlockImportOperation
|
||||
>,
|
||||
{
|
||||
let keystore_container = KeystoreContainer::new(&config.keystore)?;
|
||||
|
||||
@@ -208,16 +236,7 @@ where
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
|
||||
let (client, backend) = {
|
||||
let db_config = sc_client_db::DatabaseSettings {
|
||||
trie_cache_maximum_size: config.trie_cache_maximum_size,
|
||||
state_pruning: config.state_pruning.clone(),
|
||||
source: config.database.clone(),
|
||||
blocks_pruning: config.blocks_pruning,
|
||||
};
|
||||
|
||||
let backend = new_db_backend(db_config)?;
|
||||
|
||||
let client = {
|
||||
let extensions = sc_client_api::execution_extensions::ExecutionExtensions::new(
|
||||
config.execution_strategies.clone(),
|
||||
Some(keystore_container.sync_keystore()),
|
||||
@@ -244,7 +263,7 @@ where
|
||||
let client = new_client(
|
||||
backend.clone(),
|
||||
executor,
|
||||
chain_spec.as_storage_builder(),
|
||||
genesis_block_builder,
|
||||
fork_blocks,
|
||||
bad_blocks,
|
||||
extensions,
|
||||
@@ -263,7 +282,7 @@ where
|
||||
},
|
||||
)?;
|
||||
|
||||
(client, backend)
|
||||
client
|
||||
};
|
||||
|
||||
Ok((client, backend, keystore_container, task_manager))
|
||||
@@ -282,10 +301,10 @@ where
|
||||
}
|
||||
|
||||
/// Create an instance of client backed by given backend.
|
||||
pub fn new_client<E, Block, RA>(
|
||||
pub fn new_client<E, Block, RA, G>(
|
||||
backend: Arc<Backend<Block>>,
|
||||
executor: E,
|
||||
genesis_storage: &dyn BuildStorage,
|
||||
genesis_block_builder: G,
|
||||
fork_blocks: ForkBlocks<Block>,
|
||||
bad_blocks: BadBlocks<Block>,
|
||||
execution_extensions: ExecutionExtensions<Block>,
|
||||
@@ -305,6 +324,10 @@ pub fn new_client<E, Block, RA>(
|
||||
where
|
||||
Block: BlockT,
|
||||
E: CodeExecutor + RuntimeVersionOf,
|
||||
G: BuildGenesisBlock<
|
||||
Block,
|
||||
BlockImportOperation = <Backend<Block> as sc_client_api::backend::Backend<Block>>::BlockImportOperation
|
||||
>,
|
||||
{
|
||||
let executor = crate::client::LocalCallExecutor::new(
|
||||
backend.clone(),
|
||||
@@ -316,7 +339,7 @@ where
|
||||
crate::client::Client::new(
|
||||
backend,
|
||||
executor,
|
||||
genesis_storage,
|
||||
genesis_block_builder,
|
||||
fork_blocks,
|
||||
bad_blocks,
|
||||
prometheus_registry,
|
||||
|
||||
@@ -377,24 +377,27 @@ mod tests {
|
||||
// LocalCallExecutor directly later on
|
||||
let client_config = ClientConfig::default();
|
||||
|
||||
// client is used for the convenience of creating and inserting the genesis block.
|
||||
let _client = substrate_test_runtime_client::client::new_with_backend::<
|
||||
_,
|
||||
_,
|
||||
runtime::Block,
|
||||
_,
|
||||
runtime::RuntimeApi,
|
||||
>(
|
||||
let genesis_block_builder = crate::GenesisBlockBuilder::new(
|
||||
&substrate_test_runtime_client::GenesisParameters::default().genesis_storage(),
|
||||
!client_config.no_genesis,
|
||||
backend.clone(),
|
||||
executor.clone(),
|
||||
&substrate_test_runtime_client::GenesisParameters::default().genesis_storage(),
|
||||
None,
|
||||
Box::new(TaskExecutor::new()),
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
.expect("Creates a client");
|
||||
.expect("Creates genesis block builder");
|
||||
|
||||
// client is used for the convenience of creating and inserting the genesis block.
|
||||
let _client =
|
||||
crate::client::new_with_backend::<_, _, runtime::Block, _, runtime::RuntimeApi>(
|
||||
backend.clone(),
|
||||
executor.clone(),
|
||||
genesis_block_builder,
|
||||
None,
|
||||
Box::new(TaskExecutor::new()),
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
.expect("Creates a client");
|
||||
|
||||
let call_executor = LocalCallExecutor {
|
||||
backend: backend.clone(),
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
use super::{
|
||||
block_rules::{BlockRules, LookupResult as BlockLookupResult},
|
||||
genesis,
|
||||
genesis::BuildGenesisBlock,
|
||||
};
|
||||
use log::{info, trace, warn};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
@@ -70,7 +70,7 @@ use sp_runtime::{
|
||||
Block as BlockT, BlockIdTo, HashFor, Header as HeaderT, NumberFor, One,
|
||||
SaturatedConversion, Zero,
|
||||
},
|
||||
BuildStorage, Digest, Justification, Justifications, StateVersion,
|
||||
Digest, Justification, Justifications, StateVersion,
|
||||
};
|
||||
use sp_state_machine::{
|
||||
prove_child_read, prove_range_read_with_child_with_size, prove_read,
|
||||
@@ -155,9 +155,10 @@ enum PrepareStorageChangesResult<B: backend::Backend<Block>, Block: BlockT> {
|
||||
|
||||
/// Create an instance of in-memory client.
|
||||
#[cfg(feature = "test-helpers")]
|
||||
pub fn new_in_mem<E, Block, S, RA>(
|
||||
pub fn new_in_mem<E, Block, G, RA>(
|
||||
backend: Arc<in_mem::Backend<Block>>,
|
||||
executor: E,
|
||||
genesis_storage: &S,
|
||||
genesis_block_builder: G,
|
||||
keystore: Option<SyncCryptoStorePtr>,
|
||||
prometheus_registry: Option<Registry>,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
@@ -168,13 +169,16 @@ pub fn new_in_mem<E, Block, S, RA>(
|
||||
>
|
||||
where
|
||||
E: CodeExecutor + RuntimeVersionOf,
|
||||
S: BuildStorage,
|
||||
Block: BlockT,
|
||||
G: BuildGenesisBlock<
|
||||
Block,
|
||||
BlockImportOperation = <in_mem::Backend<Block> as backend::Backend<Block>>::BlockImportOperation,
|
||||
>,
|
||||
{
|
||||
new_with_backend(
|
||||
Arc::new(in_mem::Backend::new()),
|
||||
backend,
|
||||
executor,
|
||||
genesis_storage,
|
||||
genesis_block_builder,
|
||||
keystore,
|
||||
spawn_handle,
|
||||
prometheus_registry,
|
||||
@@ -214,10 +218,10 @@ impl<Block: BlockT> Default for ClientConfig<Block> {
|
||||
/// Create a client with the explicitly provided backend.
|
||||
/// This is useful for testing backend implementations.
|
||||
#[cfg(feature = "test-helpers")]
|
||||
pub fn new_with_backend<B, E, Block, S, RA>(
|
||||
pub fn new_with_backend<B, E, Block, G, RA>(
|
||||
backend: Arc<B>,
|
||||
executor: E,
|
||||
build_genesis_storage: &S,
|
||||
genesis_block_builder: G,
|
||||
keystore: Option<SyncCryptoStorePtr>,
|
||||
spawn_handle: Box<dyn SpawnNamed>,
|
||||
prometheus_registry: Option<Registry>,
|
||||
@@ -226,7 +230,10 @@ pub fn new_with_backend<B, E, Block, S, RA>(
|
||||
) -> sp_blockchain::Result<Client<B, LocalCallExecutor<Block, B, E>, Block, RA>>
|
||||
where
|
||||
E: CodeExecutor + RuntimeVersionOf,
|
||||
S: BuildStorage,
|
||||
G: BuildGenesisBlock<
|
||||
Block,
|
||||
BlockImportOperation = <B as backend::Backend<Block>>::BlockImportOperation,
|
||||
>,
|
||||
Block: BlockT,
|
||||
B: backend::LocalBackend<Block> + 'static,
|
||||
{
|
||||
@@ -247,7 +254,7 @@ where
|
||||
Client::new(
|
||||
backend,
|
||||
call_executor,
|
||||
build_genesis_storage,
|
||||
genesis_block_builder,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
prometheus_registry,
|
||||
@@ -347,26 +354,25 @@ where
|
||||
Block::Header: Clone,
|
||||
{
|
||||
/// Creates new Substrate Client with given blockchain and code executor.
|
||||
pub fn new(
|
||||
pub fn new<G>(
|
||||
backend: Arc<B>,
|
||||
executor: E,
|
||||
build_genesis_storage: &dyn BuildStorage,
|
||||
genesis_block_builder: G,
|
||||
fork_blocks: ForkBlocks<Block>,
|
||||
bad_blocks: BadBlocks<Block>,
|
||||
prometheus_registry: Option<Registry>,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
config: ClientConfig<Block>,
|
||||
) -> sp_blockchain::Result<Self> {
|
||||
) -> sp_blockchain::Result<Self>
|
||||
where
|
||||
G: BuildGenesisBlock<
|
||||
Block,
|
||||
BlockImportOperation = <B as backend::Backend<Block>>::BlockImportOperation,
|
||||
>,
|
||||
{
|
||||
let info = backend.blockchain().info();
|
||||
if info.finalized_state.is_none() {
|
||||
let genesis_storage =
|
||||
build_genesis_storage.build_storage().map_err(sp_blockchain::Error::Storage)?;
|
||||
let genesis_state_version =
|
||||
Self::resolve_state_version_from_wasm(&genesis_storage, &executor)?;
|
||||
let mut op = backend.begin_operation()?;
|
||||
let state_root =
|
||||
op.set_genesis_state(genesis_storage, !config.no_genesis, genesis_state_version)?;
|
||||
let genesis_block = genesis::construct_genesis_block::<Block>(state_root);
|
||||
let (genesis_block, mut op) = genesis_block_builder.build_genesis_block()?;
|
||||
info!(
|
||||
"🔨 Initializing Genesis block/state (state: {}, header-hash: {})",
|
||||
genesis_block.header().state_root(),
|
||||
@@ -379,13 +385,8 @@ where
|
||||
} else {
|
||||
NewBlockState::Normal
|
||||
};
|
||||
op.set_block_data(
|
||||
genesis_block.deconstruct().0,
|
||||
Some(vec![]),
|
||||
None,
|
||||
None,
|
||||
block_state,
|
||||
)?;
|
||||
let (header, body) = genesis_block.deconstruct();
|
||||
op.set_block_data(header, Some(body), None, None, block_state)?;
|
||||
backend.commit_operation(op)?;
|
||||
}
|
||||
|
||||
@@ -640,7 +641,7 @@ where
|
||||
// This is use by fast sync for runtime version to be resolvable from
|
||||
// changes.
|
||||
let state_version =
|
||||
Self::resolve_state_version_from_wasm(&storage, &self.executor)?;
|
||||
resolve_state_version_from_wasm(&storage, &self.executor)?;
|
||||
let state_root = operation.op.reset_storage(storage, state_version)?;
|
||||
if state_root != *import_headers.post().state_root() {
|
||||
// State root mismatch when importing state. This should not happen in
|
||||
@@ -1104,34 +1105,37 @@ where
|
||||
trace!("Collected {} uncles", uncles.len());
|
||||
Ok(uncles)
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_state_version_from_wasm(
|
||||
storage: &Storage,
|
||||
executor: &E,
|
||||
) -> sp_blockchain::Result<StateVersion> {
|
||||
if let Some(wasm) = storage.top.get(well_known_keys::CODE) {
|
||||
let mut ext = sp_state_machine::BasicExternalities::new_empty(); // just to read runtime version.
|
||||
/// Return the genesis state version given the genesis storage and executor.
|
||||
pub fn resolve_state_version_from_wasm<E>(
|
||||
storage: &Storage,
|
||||
executor: &E,
|
||||
) -> sp_blockchain::Result<StateVersion>
|
||||
where
|
||||
E: RuntimeVersionOf,
|
||||
{
|
||||
if let Some(wasm) = storage.top.get(well_known_keys::CODE) {
|
||||
let mut ext = sp_state_machine::BasicExternalities::new_empty(); // just to read runtime version.
|
||||
|
||||
let code_fetcher = sp_core::traits::WrappedRuntimeCode(wasm.as_slice().into());
|
||||
let runtime_code = sp_core::traits::RuntimeCode {
|
||||
code_fetcher: &code_fetcher,
|
||||
heap_pages: None,
|
||||
hash: {
|
||||
use std::hash::{Hash, Hasher};
|
||||
let mut state = DefaultHasher::new();
|
||||
wasm.hash(&mut state);
|
||||
state.finish().to_le_bytes().to_vec()
|
||||
},
|
||||
};
|
||||
let runtime_version =
|
||||
RuntimeVersionOf::runtime_version(executor, &mut ext, &runtime_code)
|
||||
.map_err(|e| sp_blockchain::Error::VersionInvalid(e.to_string()))?;
|
||||
Ok(runtime_version.state_version())
|
||||
} else {
|
||||
Err(sp_blockchain::Error::VersionInvalid(
|
||||
"Runtime missing from initial storage, could not read state version.".to_string(),
|
||||
))
|
||||
}
|
||||
let code_fetcher = sp_core::traits::WrappedRuntimeCode(wasm.as_slice().into());
|
||||
let runtime_code = sp_core::traits::RuntimeCode {
|
||||
code_fetcher: &code_fetcher,
|
||||
heap_pages: None,
|
||||
hash: {
|
||||
use std::hash::{Hash, Hasher};
|
||||
let mut state = DefaultHasher::new();
|
||||
wasm.hash(&mut state);
|
||||
state.finish().to_le_bytes().to_vec()
|
||||
},
|
||||
};
|
||||
let runtime_version = RuntimeVersionOf::runtime_version(executor, &mut ext, &runtime_code)
|
||||
.map_err(|e| sp_blockchain::Error::VersionInvalid(e.to_string()))?;
|
||||
Ok(runtime_version.state_version())
|
||||
} else {
|
||||
Err(sp_blockchain::Error::VersionInvalid(
|
||||
"Runtime missing from initial storage, could not read state version.".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,14 @@
|
||||
|
||||
//! Tool for creating the genesis block.
|
||||
|
||||
use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Zero};
|
||||
use sc_client_api::{backend::Backend, BlockImportOperation};
|
||||
use sc_executor::RuntimeVersionOf;
|
||||
use sp_core::storage::Storage;
|
||||
use sp_runtime::{
|
||||
traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Zero},
|
||||
BuildStorage,
|
||||
};
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
/// Create a genesis block, given the initial storage.
|
||||
pub fn construct_genesis_block<Block: BlockT>(state_root: Block::Hash) -> Block {
|
||||
@@ -38,3 +45,61 @@ pub fn construct_genesis_block<Block: BlockT>(state_root: Block::Hash) -> Block
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Trait for building the genesis block.
|
||||
pub trait BuildGenesisBlock<Block: BlockT> {
|
||||
/// The import operation used to import the genesis block into the backend.
|
||||
type BlockImportOperation;
|
||||
|
||||
/// Returns the built genesis block along with the block import operation
|
||||
/// after setting the genesis storage.
|
||||
fn build_genesis_block(self) -> sp_blockchain::Result<(Block, Self::BlockImportOperation)>;
|
||||
}
|
||||
|
||||
/// Default genesis block builder in Substrate.
|
||||
pub struct GenesisBlockBuilder<Block: BlockT, B, E> {
|
||||
genesis_storage: Storage,
|
||||
commit_genesis_state: bool,
|
||||
backend: Arc<B>,
|
||||
executor: E,
|
||||
_phantom: PhantomData<Block>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT, B: Backend<Block>, E: RuntimeVersionOf> GenesisBlockBuilder<Block, B, E> {
|
||||
/// Constructs a new instance of [`GenesisBlockBuilder`].
|
||||
pub fn new(
|
||||
build_genesis_storage: &dyn BuildStorage,
|
||||
commit_genesis_state: bool,
|
||||
backend: Arc<B>,
|
||||
executor: E,
|
||||
) -> sp_blockchain::Result<Self> {
|
||||
let genesis_storage =
|
||||
build_genesis_storage.build_storage().map_err(sp_blockchain::Error::Storage)?;
|
||||
Ok(Self {
|
||||
genesis_storage,
|
||||
commit_genesis_state,
|
||||
backend,
|
||||
executor,
|
||||
_phantom: PhantomData::<Block>,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT, B: Backend<Block>, E: RuntimeVersionOf> BuildGenesisBlock<Block>
|
||||
for GenesisBlockBuilder<Block, B, E>
|
||||
{
|
||||
type BlockImportOperation = <B as Backend<Block>>::BlockImportOperation;
|
||||
|
||||
fn build_genesis_block(self) -> sp_blockchain::Result<(Block, Self::BlockImportOperation)> {
|
||||
let Self { genesis_storage, commit_genesis_state, backend, executor, _phantom } = self;
|
||||
|
||||
let genesis_state_version =
|
||||
crate::resolve_state_version_from_wasm(&genesis_storage, &executor)?;
|
||||
let mut op = backend.begin_operation()?;
|
||||
let state_root =
|
||||
op.set_genesis_state(genesis_storage, commit_genesis_state, genesis_state_version)?;
|
||||
let genesis_block = construct_genesis_block::<Block>(state_root);
|
||||
|
||||
Ok((genesis_block, op))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ mod wasm_substitutes;
|
||||
|
||||
pub use self::{
|
||||
call_executor::LocalCallExecutor,
|
||||
client::{Client, ClientConfig},
|
||||
client::{resolve_state_version_from_wasm, Client, ClientConfig},
|
||||
};
|
||||
|
||||
#[cfg(feature = "test-helpers")]
|
||||
|
||||
@@ -34,6 +34,7 @@ pub use sc_network_common::{
|
||||
|
||||
use prometheus_endpoint::Registry;
|
||||
use sc_chain_spec::ChainSpec;
|
||||
use sc_network::config::SyncMode;
|
||||
pub use sc_telemetry::TelemetryEndpoints;
|
||||
pub use sc_transaction_pool::Options as TransactionPoolOptions;
|
||||
use sp_core::crypto::SecretString;
|
||||
@@ -238,6 +239,22 @@ impl Configuration {
|
||||
};
|
||||
ProtocolId::from(protocol_id_full)
|
||||
}
|
||||
|
||||
/// Returns true if the genesis state writting will be skipped while initializing the genesis
|
||||
/// block.
|
||||
pub fn no_genesis(&self) -> bool {
|
||||
matches!(self.network.sync_mode, SyncMode::Fast { .. } | SyncMode::Warp { .. })
|
||||
}
|
||||
|
||||
/// Returns the database config for creating the backend.
|
||||
pub fn db_config(&self) -> sc_client_db::DatabaseSettings {
|
||||
sc_client_db::DatabaseSettings {
|
||||
trie_cache_maximum_size: self.trie_cache_maximum_size,
|
||||
state_pruning: self.state_pruning.clone(),
|
||||
source: self.database.clone(),
|
||||
blocks_pruning: self.blocks_pruning,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Available RPC methods.
|
||||
|
||||
@@ -57,7 +57,10 @@ pub use self::{
|
||||
new_full_parts, spawn_tasks, BuildNetworkParams, KeystoreContainer, NetworkStarter,
|
||||
SpawnTasksParams, TFullBackend, TFullCallExecutor, TFullClient,
|
||||
},
|
||||
client::{ClientConfig, LocalCallExecutor},
|
||||
client::{
|
||||
genesis::{BuildGenesisBlock, GenesisBlockBuilder},
|
||||
resolve_state_version_from_wasm, ClientConfig, LocalCallExecutor,
|
||||
},
|
||||
error::Error,
|
||||
};
|
||||
pub use config::{
|
||||
|
||||
@@ -1756,17 +1756,30 @@ fn storage_keys_iter_works() {
|
||||
fn cleans_up_closed_notification_sinks_on_block_import() {
|
||||
use substrate_test_runtime_client::GenesisInit;
|
||||
|
||||
let backend = Arc::new(sc_client_api::in_mem::Backend::new());
|
||||
let executor = substrate_test_runtime_client::new_native_executor();
|
||||
let client_config = sc_service::ClientConfig::default();
|
||||
|
||||
let genesis_block_builder = sc_service::GenesisBlockBuilder::new(
|
||||
&substrate_test_runtime_client::GenesisParameters::default().genesis_storage(),
|
||||
!client_config.no_genesis,
|
||||
backend.clone(),
|
||||
executor.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// NOTE: we need to build the client here instead of using the client
|
||||
// provided by test_runtime_client otherwise we can't access the private
|
||||
// `import_notification_sinks` and `finality_notification_sinks` fields.
|
||||
let mut client = new_in_mem::<_, Block, _, RuntimeApi>(
|
||||
substrate_test_runtime_client::new_native_executor(),
|
||||
&substrate_test_runtime_client::GenesisParameters::default().genesis_storage(),
|
||||
backend,
|
||||
executor,
|
||||
genesis_block_builder,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Box::new(TaskExecutor::new()),
|
||||
Default::default(),
|
||||
client_config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ impl<Block: BlockT, ExecutorDispatch, Backend, G: GenesisInit>
|
||||
)
|
||||
where
|
||||
ExecutorDispatch:
|
||||
sc_client_api::CallExecutor<Block> + sc_executor::RuntimeVersionOf + 'static,
|
||||
sc_client_api::CallExecutor<Block> + sc_executor::RuntimeVersionOf + Clone + 'static,
|
||||
Backend: sc_client_api::backend::Backend<Block>,
|
||||
<Backend as sc_client_api::backend::Backend<Block>>::OffchainStorage: 'static,
|
||||
{
|
||||
@@ -223,19 +223,29 @@ impl<Block: BlockT, ExecutorDispatch, Backend, G: GenesisInit>
|
||||
storage
|
||||
};
|
||||
|
||||
let client_config = ClientConfig {
|
||||
offchain_indexing_api: self.enable_offchain_indexing_api,
|
||||
no_genesis: self.no_genesis,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let genesis_block_builder = sc_service::GenesisBlockBuilder::new(
|
||||
&storage,
|
||||
!client_config.no_genesis,
|
||||
self.backend.clone(),
|
||||
executor.clone(),
|
||||
)
|
||||
.expect("Creates genesis block builder");
|
||||
|
||||
let client = client::Client::new(
|
||||
self.backend.clone(),
|
||||
executor,
|
||||
&storage,
|
||||
genesis_block_builder,
|
||||
self.fork_blocks,
|
||||
self.bad_blocks,
|
||||
None,
|
||||
None,
|
||||
ClientConfig {
|
||||
offchain_indexing_api: self.enable_offchain_indexing_api,
|
||||
no_genesis: self.no_genesis,
|
||||
..Default::default()
|
||||
},
|
||||
client_config,
|
||||
)
|
||||
.expect("Creates new client");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user