1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
use {
18
    parity_scale_codec::Encode,
19
    sc_chain_spec::{construct_genesis_block, ChainSpec},
20
    sp_runtime::{
21
        traits::{Block as BlockT, Hash as HashT, Header as HeaderT},
22
        StateVersion,
23
    },
24
};
25

            
26
/// Generate the genesis block from a given ChainSpec.
27
pub fn generate_genesis_block<Block: BlockT>(
28
    chain_spec: &dyn ChainSpec,
29
    genesis_state_version: StateVersion,
30
) -> Result<Block, String> {
31
    let storage = chain_spec.build_storage()?;
32

            
33
    let child_roots = storage.children_default.iter().map(|(sk, child_content)| {
34
        let state_root = <<<Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
35
            child_content.data.clone().into_iter().collect(),
36
            genesis_state_version,
37
        );
38
        (sk.clone(), state_root.encode())
39
    });
40
    let state_root = <<<Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
41
        storage.top.clone().into_iter().chain(child_roots).collect(),
42
        genesis_state_version,
43
    );
44

            
45
    Ok(construct_genesis_block(state_root, genesis_state_version))
46
}