domain_block_builder/
genesis_block_builder.rs1use sc_chain_spec::{BuildGenesisBlock, construct_genesis_block, resolve_state_version_from_wasm};
4use sc_client_api::{Backend, BlockImportOperation};
5use sc_executor::RuntimeVersionOf;
6use sp_api::ProvideRuntimeApi;
7use sp_blockchain::HeaderBackend;
8use sp_core::H256;
9use sp_core::storage::Storage;
10use sp_domains::{DomainId, DomainsApi};
11use sp_runtime::BuildStorage;
12use sp_runtime::traits::{Block as BlockT, HashingFor};
13use std::marker::PhantomData;
14use std::sync::Arc;
15
16pub struct CustomGenesisBlockBuilder<CClient, CBlock: BlockT, Block: BlockT, B, E> {
18 domain_id: DomainId,
19 consensus_client: Arc<CClient>,
20 genesis_storage: Storage,
21 commit_genesis_state: bool,
22 backend: Arc<B>,
23 executor: E,
24 _data: PhantomData<(CBlock, Block)>,
25}
26
27impl<CClient, CBlock, Block: BlockT, B: Backend<Block>, E: RuntimeVersionOf>
28 CustomGenesisBlockBuilder<CClient, CBlock, Block, B, E>
29where
30 Block: BlockT,
31 B: Backend<Block>,
32 E: RuntimeVersionOf,
33 CBlock: BlockT,
34{
35 pub fn new(
37 domain_id: DomainId,
38 consensus_client: Arc<CClient>,
39 build_genesis_storage: &dyn BuildStorage,
40 commit_genesis_state: bool,
41 backend: Arc<B>,
42 executor: E,
43 ) -> sp_blockchain::Result<Self> {
44 let genesis_storage = build_genesis_storage
45 .build_storage()
46 .map_err(sp_blockchain::Error::Storage)?;
47 Ok(Self {
48 domain_id,
49 consensus_client,
50 genesis_storage,
51 commit_genesis_state,
52 backend,
53 executor,
54 _data: Default::default(),
55 })
56 }
57}
58
59impl<CClient, CBlock, Block: BlockT, B: Backend<Block>, E: RuntimeVersionOf>
60 BuildGenesisBlock<Block> for CustomGenesisBlockBuilder<CClient, CBlock, Block, B, E>
61where
62 Block: BlockT,
63 Block::Hash: From<H256>,
64 B: Backend<Block>,
65 E: RuntimeVersionOf,
66 CBlock: BlockT,
67 CBlock::Hash: From<H256>,
68 CClient: ProvideRuntimeApi<CBlock> + HeaderBackend<CBlock>,
69 CClient::Api: DomainsApi<CBlock, Block::Header>,
70{
71 type BlockImportOperation = <B as Backend<Block>>::BlockImportOperation;
72
73 fn build_genesis_block(self) -> sp_blockchain::Result<(Block, Self::BlockImportOperation)> {
74 let Self {
75 domain_id,
76 consensus_client,
77 genesis_storage,
78 commit_genesis_state,
79 backend,
80 executor,
81 _data,
82 } = self;
83
84 let maybe_expected_state_root = {
85 let runtime_api = consensus_client.runtime_api();
86 let consensus_best_hash = consensus_client.info().best_hash;
87
88 runtime_api
89 .genesis_state_root(consensus_best_hash, domain_id)?
90 .map(Into::into)
91 };
92
93 let genesis_state_version =
94 resolve_state_version_from_wasm::<_, HashingFor<Block>>(&genesis_storage, &executor)?;
95 let mut op = backend.begin_operation()?;
96 let state_root =
97 op.set_genesis_state(genesis_storage, commit_genesis_state, genesis_state_version)?;
98
99 let genesis_block = if let Some(expected_state_root) = maybe_expected_state_root
100 && expected_state_root != state_root
101 {
102 construct_genesis_block::<Block>(expected_state_root, genesis_state_version)
103 } else {
104 construct_genesis_block::<Block>(state_root, genesis_state_version)
105 };
106
107 Ok((genesis_block, op))
108 }
109}