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
                full_rotation_mode: Default::default(),
102
            },
103
            ..Default::default()
104
        },
105
    ))
106
    .with_properties(properties)
107
    .build()
108
}
109

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

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

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

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

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

            
292
8
    serde_json::to_value(g).unwrap()
293
8
}
294

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