Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

chore: move genesis block builder to chain-spec crate. #13427

Merged
merged 9 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/block-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sp-blockchain = { version = "4.0.0-dev", path = "../../primitives/blockchain" }
sp-core = { version = "7.0.0", path = "../../primitives/core" }
sp-inherents = { version = "4.0.0-dev", path = "../../primitives/inherents" }
sp-runtime = { version = "7.0.0", path = "../../primitives/runtime" }
sp-state-machine = { version = "0.13.0", path = "../../primitives/state-machine" }

[dev-dependencies]
sp-state-machine = { version = "0.13.0", path = "../../primitives/state-machine" }
substrate-test-runtime-client = { path = "../../test-utils/runtime/client" }
3 changes: 1 addition & 2 deletions client/block-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ use sp_runtime::{
Digest,
};

pub use sp_block_builder::BlockBuilder as BlockBuilderApi;

use sc_client_api::backend;
pub use sp_block_builder::BlockBuilder as BlockBuilderApi;

/// Used as parameter to [`BlockBuilderProvider`] to express if proof recording should be enabled.
///
Expand Down
4 changes: 4 additions & 0 deletions client/chain-spec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ targets = ["x86_64-unknown-linux-gnu"]
memmap2 = "0.5.0"
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.85"
sc-client-api = { version = "4.0.0-dev", path = "../api" }
sc-chain-spec-derive = { version = "4.0.0-dev", path = "./derive" }
sc-executor = { version = "0.10.0-dev", path = "../executor" }
sc-network-common = { version = "0.10.0-dev", path = "../network/common" }
sc-telemetry = { version = "4.0.0-dev", path = "../telemetry" }
sp-blockchain = { version = "4.0.0-dev", path = "../../primitives/blockchain" }
sp-core = { version = "7.0.0", path = "../../primitives/core" }
sp-runtime = { version = "7.0.0", path = "../../primitives/runtime" }
sp-state-machine = { version = "0.13.0", path = "../../primitives/state-machine" }
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,56 @@

//! Tool for creating the genesis block.

use std::{collections::hash_map::DefaultHasher, marker::PhantomData, sync::Arc};

use sc_client_api::{backend::Backend, BlockImportOperation};
use sc_executor::RuntimeVersionOf;
use sp_core::storage::Storage;
use sp_core::storage::{well_known_keys, StateVersion, Storage};
use sp_runtime::{
traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Zero},
BuildStorage,
};
use std::{marker::PhantomData, sync::Arc};

/// Return the 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(),
))
}
}

/// Create a genesis block, given the initial storage.
pub fn construct_genesis_block<Block: BlockT>(state_root: Block::Hash) -> Block {
pub fn construct_genesis_block<Block: BlockT>(
state_root: Block::Hash,
state_version: StateVersion,
) -> Block {
let extrinsics_root = <<<Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
Vec::new(),
sp_runtime::StateVersion::V0,
state_version,
);

Block::new(
Expand Down Expand Up @@ -93,12 +129,11 @@ impl<Block: BlockT, B: Backend<Block>, E: RuntimeVersionOf> BuildGenesisBlock<Bl
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 genesis_state_version = 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);
let genesis_block = construct_genesis_block::<Block>(state_root, genesis_state_version);

Ok((genesis_block, op))
}
Expand Down
11 changes: 8 additions & 3 deletions client/chain-spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,15 @@

mod chain_spec;
mod extension;
mod genesis;

pub use chain_spec::{ChainSpec as GenericChainSpec, NoExtension};
pub use extension::{
get_extension, get_extension_mut, Extension, Fork, Forks, GetExtension, Group,
pub use self::{
chain_spec::{ChainSpec as GenericChainSpec, NoExtension},
extension::{get_extension, get_extension_mut, Extension, Fork, Forks, GetExtension, Group},
genesis::{
construct_genesis_block, resolve_state_version_from_wasm, BuildGenesisBlock,
GenesisBlockBuilder,
},
};
pub use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup};

Expand Down
50 changes: 8 additions & 42 deletions client/service/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@

//! Substrate Client

use super::{
block_rules::{BlockRules, LookupResult as BlockLookupResult},
genesis::BuildGenesisBlock,
};
use super::block_rules::{BlockRules, LookupResult as BlockLookupResult};
use futures::{FutureExt, StreamExt};
use log::{error, info, trace, warn};
use parking_lot::{Mutex, RwLock};
use prometheus_endpoint::Registry;
use rand::Rng;
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider, RecordProof};
use sc_chain_spec::{resolve_state_version_from_wasm, BuildGenesisBlock};
use sc_client_api::{
backend::{
self, apply_aux, BlockImportOperation, ClientImportOperation, FinalizeSummary, Finalizer,
Expand All @@ -46,7 +44,7 @@ use sc_client_api::{
use sc_consensus::{
BlockCheckParams, BlockImportParams, ForkChoiceStrategy, ImportResult, StateAction,
};
use sc_executor::{RuntimeVersion, RuntimeVersionOf};
use sc_executor::RuntimeVersion;
use sc_telemetry::{telemetry, TelemetryHandle, SUBSTRATE_INFO};
use sp_api::{
ApiExt, ApiRef, CallApiAt, CallApiAtParams, ConstructRuntimeApi, Core as CoreApi,
Expand All @@ -61,8 +59,8 @@ use sp_consensus::{BlockOrigin, BlockStatus, Error as ConsensusError};
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender};
use sp_core::{
storage::{
well_known_keys, ChildInfo, ChildType, PrefixedStorageKey, Storage, StorageChild,
StorageData, StorageKey,
well_known_keys, ChildInfo, ChildType, PrefixedStorageKey, StorageChild, StorageData,
StorageKey,
},
traits::SpawnNamed,
};
Expand All @@ -84,7 +82,7 @@ use sp_state_machine::{
};
use sp_trie::{CompactProof, StorageProof};
use std::{
collections::{hash_map::DefaultHasher, HashMap, HashSet},
collections::{HashMap, HashSet},
marker::PhantomData,
path::PathBuf,
sync::Arc,
Expand Down Expand Up @@ -171,7 +169,7 @@ pub fn new_in_mem<E, Block, G, RA>(
Client<in_mem::Backend<Block>, LocalCallExecutor<Block, in_mem::Backend<Block>, E>, Block, RA>,
>
where
E: CodeExecutor + RuntimeVersionOf,
E: CodeExecutor + sc_executor::RuntimeVersionOf,
Block: BlockT,
G: BuildGenesisBlock<
Block,
Expand Down Expand Up @@ -232,7 +230,7 @@ pub fn new_with_backend<B, E, Block, G, RA>(
config: ClientConfig<Block>,
) -> sp_blockchain::Result<Client<B, LocalCallExecutor<Block, B, E>, Block, RA>>
where
E: CodeExecutor + RuntimeVersionOf,
E: CodeExecutor + sc_executor::RuntimeVersionOf,
G: BuildGenesisBlock<
Block,
BlockImportOperation = <B as backend::Backend<Block>>::BlockImportOperation,
Expand Down Expand Up @@ -1164,38 +1162,6 @@ where
}
}

/// 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(),
))
}
}

impl<B, E, Block, RA> UsageProvider<Block> for Client<B, E, Block, RA>
where
B: backend::Backend<Block>,
Expand Down
3 changes: 1 addition & 2 deletions client/service/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@
mod block_rules;
mod call_executor;
mod client;
pub mod genesis;
mod wasm_override;
mod wasm_substitutes;

pub use self::{
call_executor::LocalCallExecutor,
client::{resolve_state_version_from_wasm, Client, ClientConfig},
client::{Client, ClientConfig},
};

#[cfg(feature = "test-helpers")]
Expand Down
11 changes: 7 additions & 4 deletions client/service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ pub use self::{
new_full_parts, spawn_tasks, BuildNetworkParams, KeystoreContainer, NetworkStarter,
SpawnTasksParams, TFullBackend, TFullCallExecutor, TFullClient,
},
client::{
genesis::{BuildGenesisBlock, GenesisBlockBuilder},
resolve_state_version_from_wasm, ClientConfig, LocalCallExecutor,
},
client::{ClientConfig, LocalCallExecutor},
error::Error,
};

pub use sc_chain_spec::{
construct_genesis_block, resolve_state_version_from_wasm, BuildGenesisBlock,
GenesisBlockBuilder,
};

pub use config::{
BasePath, BlocksPruning, Configuration, DatabaseSource, PruningMode, Role, RpcMethods, TaskType,
};
Expand Down
1 change: 1 addition & 0 deletions test-utils/runtime/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"]
codec = { package = "parity-scale-codec", version = "3.2.2" }
futures = "0.3.21"
sc-block-builder = { version = "0.10.0-dev", path = "../../../client/block-builder" }
sc-chain-spec = { version = "4.0.0-dev", path = "../../../client/chain-spec" }
sc-client-api = { version = "4.0.0-dev", path = "../../../client/api" }
sc-consensus = { version = "0.10.0-dev", path = "../../../client/consensus/common" }
sp-api = { version = "4.0.0-dev", path = "../../../primitives/api" }
Expand Down
17 changes: 7 additions & 10 deletions test-utils/runtime/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub use substrate_test_runtime as runtime;

pub use self::block_builder_ext::BlockBuilderExt;

use sc_chain_spec::construct_genesis_block;
use sp_api::StateVersion;
use sp_core::{
sr25519,
storage::{ChildInfo, Storage, StorageChild},
Expand Down Expand Up @@ -122,7 +124,7 @@ impl GenesisParameters {
}
}

impl substrate_test_client::GenesisInit for GenesisParameters {
impl GenesisInit for GenesisParameters {
fn genesis_storage(&self) -> Storage {
use codec::Encode;

Expand All @@ -148,7 +150,7 @@ impl substrate_test_client::GenesisInit for GenesisParameters {
storage.top.clone().into_iter().chain(child_roots).collect(),
sp_runtime::StateVersion::V1,
);
let block: runtime::Block = client::genesis::construct_genesis_block(state_root);
let block: runtime::Block = construct_genesis_block(state_root, StateVersion::V1);
storage.top.extend(additional_storage_with_genesis(&block));

storage
Expand Down Expand Up @@ -260,7 +262,7 @@ impl<B> TestClientBuilderExt<B>
client::LocalCallExecutor<
substrate_test_runtime::Block,
B,
sc_executor::NativeElseWasmExecutor<LocalExecutorDispatch>,
NativeElseWasmExecutor<LocalExecutorDispatch>,
>,
B,
> where
Expand Down Expand Up @@ -288,11 +290,6 @@ pub fn new() -> Client<Backend> {
}

/// Create a new native executor.
pub fn new_native_executor() -> sc_executor::NativeElseWasmExecutor<LocalExecutorDispatch> {
sc_executor::NativeElseWasmExecutor::new(
sc_executor::WasmExecutionMethod::Interpreted,
None,
8,
2,
)
pub fn new_native_executor() -> NativeElseWasmExecutor<LocalExecutorDispatch> {
NativeElseWasmExecutor::new(sc_executor::WasmExecutionMethod::Interpreted, None, 8, 2)
}
6 changes: 3 additions & 3 deletions test-utils/runtime/src/genesismap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
use super::{system, wasm_binary_unwrap, AccountId, AuthorityId, Runtime};
use codec::{Encode, Joiner, KeyedVec};
use frame_support::traits::GenesisBuild;
use sc_service::client::genesis;
use sc_service::construct_genesis_block;
use sp_core::{
map,
storage::{well_known_keys, Storage},
storage::{well_known_keys, StateVersion, Storage},
};
use sp_io::hashing::{blake2_256, twox_128};
use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT};
Expand Down Expand Up @@ -106,7 +106,7 @@ pub fn insert_genesis_block(storage: &mut Storage) -> sp_core::hash::H256 {
storage.top.clone().into_iter().collect(),
sp_runtime::StateVersion::V1,
);
let block: crate::Block = genesis::construct_genesis_block(state_root);
let block: crate::Block = construct_genesis_block(state_root, StateVersion::V1);
let genesis_hash = block.header.hash();
storage.top.extend(additional_storage_with_genesis(&block));
genesis_hash
Expand Down