Skip to content

Commit

Permalink
Support custom genesis block (paritytech#12291)
Browse files Browse the repository at this point in the history
* 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`
  • Loading branch information
liuchengxu authored and ltfschoen committed Feb 22, 2023
1 parent 792830f commit 0464ce0
Show file tree
Hide file tree
Showing 10 changed files with 261 additions and 113 deletions.
30 changes: 20 additions & 10 deletions bin/node/testing/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
59 changes: 41 additions & 18 deletions client/service/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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};

Expand Down Expand Up @@ -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>,
Expand All @@ -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)?;

Expand All @@ -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()),
Expand All @@ -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,
Expand All @@ -263,7 +282,7 @@ where
},
)?;

(client, backend)
client
};

Ok((client, backend, keystore_container, task_manager))
Expand All @@ -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>,
Expand All @@ -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(),
Expand All @@ -316,7 +339,7 @@ where
crate::client::Client::new(
backend,
executor,
genesis_storage,
genesis_block_builder,
fork_blocks,
bad_blocks,
prometheus_registry,
Expand Down
33 changes: 18 additions & 15 deletions client/service/src/client/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Loading

0 comments on commit 0464ce0

Please sign in to comment.