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
#![cfg(test)]
18

            
19
use {
20
    crate::{
21
        tests::common::*, Balances, CollatorConfiguration, ContainerRegistrar, DataPreservers,
22
    },
23
    cumulus_primitives_core::{relay_chain::HeadData, ParaId},
24
    dancelight_runtime_constants::currency::EXISTENTIAL_DEPOSIT,
25
    frame_support::{assert_noop, assert_ok, BoundedVec},
26
    pallet_registrar_runtime_api::{
27
        runtime_decl_for_registrar_api::RegistrarApi, ContainerChainGenesisData,
28
    },
29
    sp_std::vec,
30
};
31

            
32
#[test]
33
1
fn genesis_balances() {
34
1
    ExtBuilder::default()
35
1
        .with_balances(vec![
36
1
            // Alice gets 10k extra tokens for her mapping deposit
37
1
            (AccountId::from(ALICE), 210_000 * UNIT),
38
1
            (AccountId::from(BOB), 100_000 * UNIT),
39
1
            (AccountId::from(CHARLIE), 100_000 * UNIT),
40
1
            (AccountId::from(DAVE), 100_000 * UNIT),
41
1
        ])
42
1
        .build()
43
1
        .execute_with(|| {
44
1
            assert_eq!(
45
1
                Balances::usable_balance(AccountId::from(ALICE)) + EXISTENTIAL_DEPOSIT,
46
1
                210_000 * UNIT,
47
1
            );
48
1
            assert_eq!(
49
1
                Balances::usable_balance(AccountId::from(BOB)) + EXISTENTIAL_DEPOSIT,
50
1
                100_000 * UNIT,
51
1
            );
52
1
        });
53
1
}
54

            
55
#[test]
56
1
fn genesis_para_registrar() {
57
1
    ExtBuilder::default()
58
1
        .with_empty_parachains(vec![1001, 1002])
59
1
        .build()
60
1
        .execute_with(|| {
61
1
            assert_eq!(
62
1
                ContainerRegistrar::registered_para_ids(),
63
1
                vec![1001.into(), 1002.into()]
64
1
            );
65
1
        });
66
1
}
67

            
68
#[test]
69
1
fn genesis_para_registrar_deregister() {
70
1
    ExtBuilder::default()
71
1
        .with_empty_parachains(vec![1001, 1002])
72
1
        .build()
73
1
        .execute_with(|| {
74
1
            assert_eq!(
75
1
                ContainerRegistrar::registered_para_ids(),
76
1
                vec![1001.into(), 1002.into()]
77
1
            );
78

            
79
1
            run_to_block(2);
80
1
            assert_ok!(
81
1
                ContainerRegistrar::deregister(root_origin(), 1002.into()),
82
1
                ()
83
1
            );
84

            
85
            // Pending
86
1
            assert_eq!(
87
1
                ContainerRegistrar::pending_registered_para_ids(),
88
1
                vec![(2u32, BoundedVec::try_from(vec![1001u32.into()]).unwrap())]
89
1
            );
90

            
91
1
            run_to_session(1);
92
1
            assert_eq!(
93
1
                ContainerRegistrar::pending_registered_para_ids(),
94
1
                vec![(2u32, BoundedVec::try_from(vec![1001u32.into()]).unwrap())]
95
1
            );
96
1
            assert_eq!(
97
1
                ContainerRegistrar::registered_para_ids(),
98
1
                vec![1001.into(), 1002.into()]
99
1
            );
100

            
101
1
            run_to_session(2);
102
1
            assert_eq!(ContainerRegistrar::pending_registered_para_ids(), vec![]);
103
1
            assert_eq!(ContainerRegistrar::registered_para_ids(), vec![1001.into()]);
104
1
        });
105
1
}
106

            
107
#[test]
108
1
fn genesis_para_registrar_runtime_api() {
109
1
    ExtBuilder::default()
110
1
        .with_empty_parachains(vec![1001, 1002])
111
1
        .build()
112
1
        .execute_with(|| {
113
1
            assert_eq!(
114
1
                ContainerRegistrar::registered_para_ids(),
115
1
                vec![1001.into(), 1002.into()]
116
1
            );
117
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into(), 1002.into()]);
118

            
119
1
            run_to_block(2);
120
1
            assert_ok!(
121
1
                ContainerRegistrar::deregister(root_origin(), 1002.into()),
122
1
                ()
123
1
            );
124
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into(), 1002.into()]);
125

            
126
1
            run_to_session(1);
127
1
            assert_eq!(
128
1
                ContainerRegistrar::registered_para_ids(),
129
1
                vec![1001.into(), 1002.into()]
130
1
            );
131
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into(), 1002.into()]);
132

            
133
1
            run_to_session(2);
134
1
            assert_eq!(ContainerRegistrar::registered_para_ids(), vec![1001.into()]);
135
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into()]);
136
1
        });
137
1
}
138

            
139
#[test]
140
1
fn genesis_para_registrar_container_chain_genesis_data_runtime_api() {
141
1
    let genesis_data_1001 = empty_genesis_data();
142
1
    let genesis_data_1002 = ContainerChainGenesisData {
143
1
        storage: vec![(b"key".to_vec(), b"value".to_vec()).into()],
144
1
        name: Default::default(),
145
1
        id: Default::default(),
146
1
        fork_id: Default::default(),
147
1
        extensions: vec![],
148
1
        properties: Default::default(),
149
1
    };
150
1
    ExtBuilder::default()
151
1
        .with_para_ids(vec![
152
1
                       ParaRegistrationParams {
153
1
                para_id: 1001,
154
1
                genesis_data: genesis_data_1001.clone(),
155
1
                block_production_credits: u32::MAX,
156
1
                collator_assignment_credits: u32::MAX,
157
1
                parathread_params: None,
158
1
            },ParaRegistrationParams {
159
1
                para_id: 1002,
160
1
                genesis_data: genesis_data_1002.clone(),
161
1
                block_production_credits: u32::MAX,
162
1
                collator_assignment_credits: u32::MAX,
163
1
                parathread_params: None,
164
1
            },
165
1
        ])
166
1
        .build()
167
1
        .execute_with(|| {
168
1
            assert_eq!(
169
1
                ContainerRegistrar::registered_para_ids(),
170
1
                vec![1001.into(), 1002.into()]
171
1
            );
172
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into(), 1002.into()]);
173

            
174
1
            assert_eq!(
175
1
                Runtime::genesis_data(1001.into()).as_ref(),
176
1
                Some(&genesis_data_1001)
177
1
            );
178
1
            assert_eq!(
179
1
                Runtime::genesis_data(1002.into()).as_ref(),
180
1
                Some(&genesis_data_1002)
181
1
            );
182
1
            assert_eq!(Runtime::genesis_data(1003.into()).as_ref(), None);
183

            
184
            // This API cannot be used to get the genesis data of the orchestrator chain,
185
            // with id 100
186
            // TODO: where is that 100 defined?
187
1
            assert_eq!(Runtime::genesis_data(100.into()).as_ref(), None);
188

            
189
1
            run_to_block(2);
190
1
            assert_ok!(ContainerRegistrar::deregister(root_origin(), 1002.into()), ());
191

            
192
1
            assert_eq!(Runtime::genesis_data(1002.into()).as_ref(), Some(&genesis_data_1002), "Deregistered container chain genesis data should not be removed until after 2 sessions");
193

            
194
1
            assert_ok!(
195
1
                ContainerRegistrar::register(
196
1
                    origin_of(ALICE.into()),
197
1
                    1003.into(),
198
1
                    get_genesis_data_with_validation_code().0,
199
1
                    Some(HeadData(vec![1u8, 1u8, 1u8]))
200
1
                ),
201
1
                ()
202
1
            );
203

            
204
            // Registered container chains are inserted immediately
205
1
            assert_eq!(
206
1
                Runtime::genesis_data(1003.into()).as_ref(),
207
1
                Some(&get_genesis_data_with_validation_code().0)
208
1
            );
209

            
210
            // Deregistered container chain genesis data is removed after 2 sessions
211
1
            run_to_session(2u32);
212
1
            assert_eq!(Runtime::genesis_data(1002.into()).as_ref(), None);
213
1
        });
214
1
}
215

            
216
#[test]
217
1
fn test_configuration_on_session_change() {
218
1
    ExtBuilder::default().build().execute_with(|| {
219
1
        assert_eq!(CollatorConfiguration::config().max_collators, 100);
220
1
        assert_eq!(
221
1
            CollatorConfiguration::config().min_orchestrator_collators,
222
1
            2
223
1
        );
224
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
225

            
226
1
        assert_ok!(
227
1
            CollatorConfiguration::set_max_collators(root_origin(), 50),
228
1
            ()
229
1
        );
230
1
        run_to_session(1u32);
231
1

            
232
1
        assert_ok!(
233
1
            CollatorConfiguration::set_min_orchestrator_collators(root_origin(), 20),
234
1
            ()
235
1
        );
236
1
        assert_eq!(CollatorConfiguration::config().max_collators, 100);
237
1
        assert_eq!(
238
1
            CollatorConfiguration::config().min_orchestrator_collators,
239
1
            2
240
1
        );
241
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
242

            
243
1
        run_to_session(2u32);
244
1
        assert_ok!(
245
1
            CollatorConfiguration::set_collators_per_container(root_origin(), 10),
246
1
            ()
247
1
        );
248
1
        assert_eq!(CollatorConfiguration::config().max_collators, 50);
249
1
        assert_eq!(
250
1
            CollatorConfiguration::config().min_orchestrator_collators,
251
1
            2
252
1
        );
253
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
254

            
255
1
        run_to_session(3u32);
256
1

            
257
1
        assert_eq!(CollatorConfiguration::config().max_collators, 50);
258
1
        assert_eq!(
259
1
            CollatorConfiguration::config().min_orchestrator_collators,
260
1
            20
261
1
        );
262
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
263

            
264
1
        run_to_session(4u32);
265
1

            
266
1
        assert_eq!(CollatorConfiguration::config().max_collators, 50);
267
1
        assert_eq!(
268
1
            CollatorConfiguration::config().min_orchestrator_collators,
269
1
            20
270
1
        );
271
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 10);
272
1
    });
273
1
}
274

            
275
#[test]
276
1
fn test_cannot_mark_valid_para_with_no_bootnodes() {
277
1
    ExtBuilder::default()
278
1
        .with_balances(vec![
279
1
            // Alice gets 10k extra tokens for her mapping deposit
280
1
            (AccountId::from(ALICE), 210_000 * UNIT),
281
1
            (AccountId::from(BOB), 100_000 * UNIT),
282
1
            (AccountId::from(CHARLIE), 100_000 * UNIT),
283
1
            (AccountId::from(DAVE), 100_000 * UNIT),
284
1
        ])
285
1
        .with_collators(vec![
286
1
            (AccountId::from(ALICE), 210 * UNIT),
287
1
            (AccountId::from(BOB), 100 * UNIT),
288
1
            (AccountId::from(CHARLIE), 100 * UNIT),
289
1
            (AccountId::from(DAVE), 100 * UNIT),
290
1
        ])
291
1
        .build()
292
1
        .execute_with(|| {
293
1
            run_to_block(2);
294
1
            assert_ok!(ContainerRegistrar::register(
295
1
                origin_of(ALICE.into()),
296
1
                1001.into(),
297
1
                get_genesis_data_with_validation_code().0,
298
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
299
1
            ));
300
1
            assert_noop!(
301
1
                ContainerRegistrar::mark_valid_for_collating(root_origin(), 1001.into()),
302
1
                pallet_data_preservers::Error::<Runtime>::NoBootNodes,
303
1
            );
304
1
        });
305
1
}
306

            
307
#[test]
308
1
fn test_container_deregister_unassign_data_preserver() {
309
1
    ExtBuilder::default()
310
1
        .with_balances(vec![
311
1
            (AccountId::from(ALICE), 210_000 * UNIT),
312
1
            (AccountId::from(BOB), 100_000 * UNIT),
313
1
        ])
314
1
        .build()
315
1
        .execute_with(|| {
316
            use pallet_data_preservers::{
317
                AssignerParameterOf, ParaIdsFilter, Profile, ProfileMode, ProviderRequestOf,
318
            };
319

            
320
1
            let profile = Profile {
321
1
                url: b"test".to_vec().try_into().unwrap(),
322
1
                para_ids: ParaIdsFilter::AnyParaId,
323
1
                mode: ProfileMode::Bootnode,
324
1
                assignment_request: ProviderRequestOf::<Runtime>::Free,
325
1
            };
326
1

            
327
1
            let para_id = ParaId::from(1002);
328
1
            let profile_id = 0u64;
329
1

            
330
1
            assert_ok!(ContainerRegistrar::register(
331
1
                origin_of(ALICE.into()),
332
1
                para_id,
333
1
                get_genesis_data_with_validation_code().0,
334
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
335
1
            ));
336

            
337
1
            assert_ok!(DataPreservers::create_profile(
338
1
                origin_of(BOB.into()),
339
1
                profile.clone(),
340
1
            ));
341

            
342
            // Start assignment
343
1
            assert_ok!(DataPreservers::start_assignment(
344
1
                origin_of(ALICE.into()),
345
1
                profile_id,
346
1
                para_id,
347
1
                AssignerParameterOf::<Runtime>::Free
348
1
            ));
349
1
            assert!(pallet_data_preservers::Assignments::<Runtime>::get(para_id).contains(&0u64));
350

            
351
            // Deregister from Registrar
352
1
            assert_ok!(ContainerRegistrar::deregister(root_origin(), para_id), ());
353

            
354
            // Check DataPreserver assignment has been cleared
355
1
            assert!(pallet_data_preservers::Assignments::<Runtime>::get(para_id).is_empty());
356
1
        });
357
1
}