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
    crate::chain_spec::{
19
        account_ids, get_account_id_from_seed, invulnerables_from_seeds, Extensions,
20
    },
21
    cumulus_primitives_core::ParaId,
22
    dp_container_chain_genesis_data::{
23
        json::container_chain_genesis_data_from_path, ContainerChainGenesisData,
24
    },
25
    flashbox_runtime::{
26
        AccountId, DataPreserversConfig, MaintenanceModeConfig, MigrationsConfig, RegistrarConfig,
27
        ServicesPaymentConfig, SudoConfig,
28
    },
29
    nimbus_primitives::NimbusId,
30
    pallet_configuration::HostConfiguration,
31
    sc_service::ChainType,
32
    sp_core::sr25519,
33
    sp_runtime::Perbill,
34
};
35

            
36
/// Specialized `ChainSpec` for the normal parachain runtime.
37
pub type ChainSpec = sc_service::GenericChainSpec<Extensions>;
38

            
39
/// Generate the session keys from individual elements.
40
///
41
/// The input must be a tuple of individual keys (a single arg for now since we have just one key).
42
32
pub fn template_session_keys(keys: NimbusId) -> flashbox_runtime::SessionKeys {
43
32
    flashbox_runtime::SessionKeys { nimbus: keys }
44
32
}
45

            
46
pub fn development_config(
47
    para_id: ParaId,
48
    container_chains: Vec<String>,
49
    mock_container_chains: Vec<ParaId>,
50
    invulnerables: Vec<String>,
51
) -> ChainSpec {
52
    // Give your base currency a unit name and decimal places
53
    let mut properties = sc_chain_spec::Properties::new();
54
    properties.insert("tokenSymbol".into(), "FLASH".into());
55
    properties.insert("tokenDecimals".into(), 12.into());
56
    properties.insert("ss58Format".into(), 42.into());
57
    properties.insert("isEthereum".into(), false.into());
58

            
59
    ChainSpec::builder(
60
        flashbox_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
61
        Extensions {
62
            relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
63
            para_id: para_id.into(),
64
        },
65
    )
66
    .with_name("Flashbox Development Testnet")
67
    .with_id("flashbox_dev")
68
    .with_chain_type(ChainType::Development)
69
    .with_genesis_config(testnet_genesis(
70
        // initial collators.
71
        invulnerables_from_seeds(invulnerables.iter()),
72
        account_ids(&[
73
            "Alice",
74
            "Bob",
75
            "Charlie",
76
            "Dave",
77
            "Eve",
78
            "Ferdie",
79
            "Alice//stash",
80
            "Bob//stash",
81
            "Charlie//stash",
82
            "Dave//stash",
83
            "Eve//stash",
84
            "Ferdie//stash",
85
        ]),
86
        para_id,
87
        get_account_id_from_seed::<sr25519::Public>("Alice"),
88
        &container_chains,
89
        &mock_container_chains,
90
        pallet_configuration::GenesisConfig {
91
            config: HostConfiguration {
92
                max_collators: 100u32,
93
                min_orchestrator_collators: 1u32,
94
                max_orchestrator_collators: 1u32,
95
                collators_per_container: 2u32,
96
                full_rotation_period: 0,
97
                collators_per_parathread: 1,
98
                parathreads_per_collator: 1,
99
                target_container_chain_fullness: Perbill::from_percent(80),
100
                max_parachain_cores_percentage: None,
101
            },
102
            ..Default::default()
103
        },
104
    ))
105
    .with_properties(properties)
106
    .build()
107
}
108

            
109
8
pub fn local_flashbox_config(
110
8
    para_id: ParaId,
111
8
    container_chains: Vec<String>,
112
8
    mock_container_chains: Vec<ParaId>,
113
8
    invulnerables: Vec<String>,
114
8
) -> ChainSpec {
115
8
    // Give your base currency a unit name and decimal places
116
8
    let mut properties = sc_chain_spec::Properties::new();
117
8
    properties.insert("tokenSymbol".into(), "FLASH".into());
118
8
    properties.insert("tokenDecimals".into(), 12.into());
119
8
    properties.insert("ss58Format".into(), 42.into());
120
8
    properties.insert("isEthereum".into(), false.into());
121
8

            
122
8
    ChainSpec::builder(
123
8
        flashbox_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
124
8
        Extensions {
125
8
            relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
126
8
            para_id: para_id.into(),
127
8
        },
128
8
    )
129
8
    .with_name("Flashbox Local Testnet")
130
8
    .with_id("flashbox_local")
131
8
    .with_chain_type(ChainType::Local)
132
8
    .with_genesis_config(testnet_genesis(
133
8
        // initial collators.
134
8
        invulnerables_from_seeds(invulnerables.iter()),
135
8
        account_ids(&[
136
8
            "Alice",
137
8
            "Bob",
138
8
            "Charlie",
139
8
            "Dave",
140
8
            "Eve",
141
8
            "Ferdie",
142
8
            "Alice//stash",
143
8
            "Bob//stash",
144
8
            "Charlie//stash",
145
8
            "Dave//stash",
146
8
            "Eve//stash",
147
8
            "Ferdie//stash",
148
8
        ]),
149
8
        para_id,
150
8
        get_account_id_from_seed::<sr25519::Public>("Alice"),
151
8
        &container_chains,
152
8
        &mock_container_chains,
153
8
        pallet_configuration::GenesisConfig {
154
8
            config: HostConfiguration {
155
8
                max_collators: 100u32,
156
8
                min_orchestrator_collators: 2u32,
157
8
                max_orchestrator_collators: 5u32,
158
8
                collators_per_container: 2u32,
159
8
                full_rotation_period: 0,
160
8
                collators_per_parathread: 1,
161
8
                parathreads_per_collator: 1,
162
8
                target_container_chain_fullness: Perbill::from_percent(80),
163
8
                max_parachain_cores_percentage: None,
164
8
            },
165
8
            ..Default::default()
166
8
        },
167
8
    ))
168
8
    .with_properties(properties)
169
8
    .with_protocol_id("orchestrator")
170
8
    .build()
171
8
}
172

            
173
8
fn testnet_genesis(
174
8
    invulnerables: Vec<(AccountId, NimbusId)>,
175
8
    endowed_accounts: Vec<AccountId>,
176
8
    id: ParaId,
177
8
    root_key: AccountId,
178
8
    container_chains: &[String],
179
8
    mock_container_chains: &[ParaId],
180
8
    configuration: pallet_configuration::GenesisConfig<flashbox_runtime::Runtime>,
181
8
) -> serde_json::Value {
182
8
    let para_ids: Vec<_> = container_chains
183
8
        .iter()
184
8
        .map(|x| {
185
            container_chain_genesis_data_from_path(x).unwrap_or_else(|e| {
186
                panic!(
187
                    "Failed to build genesis data for container chain {:?}: {}",
188
                    x, e
189
                )
190
            })
191
8
        })
192
8
        .chain(
193
8
            mock_container_chains
194
8
                .iter()
195
16
                .map(|x| (*x, mock_container_chain_genesis_data(*x), vec![])),
196
8
        )
197
8
        .collect();
198
8
    // Assign 1000 block credits to all container chains registered in genesis
199
8
    // Assign 100 collator assignment credits to all container chains registered in genesis
200
8
    let para_id_credits: Vec<_> = para_ids
201
8
        .iter()
202
16
        .map(|(para_id, _genesis_data, _boot_nodes)| (*para_id, 1000, 100).into())
203
8
        .collect();
204
8
    let data_preservers_bootnodes: Vec<_> = para_ids
205
8
        .iter()
206
16
        .flat_map(|(para_id, _genesis_data, bootnodes)| {
207
16
            bootnodes.clone().into_iter().map(|bootnode| {
208
                (
209
                    *para_id,
210
                    AccountId::from([0u8; 32]),
211
                    bootnode,
212
                    flashbox_runtime::PreserversAssignementPaymentRequest::Free,
213
                    flashbox_runtime::PreserversAssignementPaymentWitness::Free,
214
                )
215
16
            })
216
16
        })
217
8
        .collect();
218
8

            
219
8
    let para_ids: Vec<_> = para_ids
220
8
        .into_iter()
221
16
        .map(|(para_id, genesis_data, _boot_nodes)| (para_id, genesis_data, None))
222
8
        .collect();
223
8

            
224
8
    let accounts_with_ed = [
225
8
        flashbox_runtime::StakingAccount::get(),
226
8
        flashbox_runtime::ParachainBondAccount::get(),
227
8
        flashbox_runtime::PendingRewardsAccount::get(),
228
8
    ];
229
8
    let g = flashbox_runtime::RuntimeGenesisConfig {
230
8
        system: Default::default(),
231
8
        balances: flashbox_runtime::BalancesConfig {
232
8
            balances: endowed_accounts
233
8
                .iter()
234
8
                .cloned()
235
96
                .map(|k| (k, 1 << 60))
236
8
                .chain(
237
8
                    accounts_with_ed
238
8
                        .iter()
239
8
                        .cloned()
240
24
                        .map(|k| (k, flashbox_runtime::EXISTENTIAL_DEPOSIT)),
241
8
                )
242
8
                .collect(),
243
8
        },
244
8
        parachain_info: flashbox_runtime::ParachainInfoConfig {
245
8
            parachain_id: id,
246
8
            ..Default::default()
247
8
        },
248
8
        invulnerables: flashbox_runtime::InvulnerablesConfig {
249
32
            invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
250
8
        },
251
8
        session: flashbox_runtime::SessionConfig {
252
8
            keys: invulnerables
253
8
                .into_iter()
254
32
                .map(|(acc, aura)| {
255
32
                    (
256
32
                        acc.clone(),                 // account id
257
32
                        acc,                         // validator id
258
32
                        template_session_keys(aura), // session keys
259
32
                    )
260
32
                })
261
8
                .collect(),
262
8
            ..Default::default()
263
8
        },
264
8
        parachain_system: Default::default(),
265
8
        configuration,
266
8
        registrar: RegistrarConfig {
267
8
            para_ids,
268
8
            phantom: Default::default(),
269
8
        },
270
8
        services_payment: ServicesPaymentConfig { para_id_credits },
271
8
        sudo: SudoConfig {
272
8
            key: Some(root_key),
273
8
        },
274
8
        migrations: MigrationsConfig {
275
8
            ..Default::default()
276
8
        },
277
8
        maintenance_mode: MaintenanceModeConfig {
278
8
            start_in_maintenance_mode: false,
279
8
            ..Default::default()
280
8
        },
281
8
        transaction_payment: Default::default(),
282
8
        tx_pause: Default::default(),
283
8
        treasury: Default::default(),
284
8
        data_preservers: DataPreserversConfig {
285
8
            bootnodes: data_preservers_bootnodes,
286
8
            ..Default::default()
287
8
        },
288
8
    };
289
8

            
290
8
    serde_json::to_value(g).unwrap()
291
8
}
292

            
293
16
fn mock_container_chain_genesis_data(para_id: ParaId) -> ContainerChainGenesisData {
294
16
    ContainerChainGenesisData {
295
16
        storage: vec![],
296
16
        name: format!("Container Chain {}", para_id).into(),
297
16
        id: format!("container-chain-{}", para_id).into(),
298
16
        fork_id: None,
299
16
        extensions: vec![],
300
16
        properties: Default::default(),
301
16
    }
302
16
}