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
        Registrar,
23
    },
24
    cumulus_primitives_core::{relay_chain::HeadData, ParaId},
25
    dancelight_runtime_constants::currency::EXISTENTIAL_DEPOSIT,
26
    frame_support::{assert_noop, assert_ok, BoundedVec},
27
    pallet_registrar_runtime_api::{
28
        runtime_decl_for_registrar_api::RegistrarApi, ContainerChainGenesisData,
29
    },
30
    sp_std::vec,
31
};
32

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

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

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

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

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

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

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

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

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

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

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

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

            
177
1
            assert_eq!(
178
1
                Runtime::genesis_data(2001.into()).as_ref(),
179
1
                Some(&genesis_data_2001)
180
1
            );
181
1
            assert_eq!(
182
1
                Runtime::genesis_data(2002.into()).as_ref(),
183
1
                Some(&genesis_data_2002)
184
1
            );
185
1
            assert_eq!(Runtime::genesis_data(2003.into()).as_ref(), None);
186

            
187
1
            run_to_block(2);
188
1
            assert_ok!(ContainerRegistrar::deregister(root_origin(), 2002.into()), ());
189

            
190
1
            assert_eq!(Runtime::genesis_data(2002.into()).as_ref(), Some(&genesis_data_2002), "Deregistered container chain genesis data should not be removed until after 2 sessions");
191
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
192
1
            assert_ok!(
193
1
                ContainerRegistrar::register(
194
1
                    origin_of(ALICE.into()),
195
1
                    2003.into(),
196
1
                    get_genesis_data_with_validation_code().0,
197
1
                    Some(HeadData(vec![1u8, 1u8, 1u8]))
198
1
                ),
199
1
                ()
200
1
            );
201

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

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

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

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

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

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

            
253
1
        run_to_session(3u32);
254
1

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

            
262
1
        run_to_session(4u32);
263
1

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

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

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

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

            
326
1
            let para_id = ParaId::from(2000);
327
1
            let profile_id = 0u64;
328
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
329
1
            assert_ok!(ContainerRegistrar::register(
330
1
                origin_of(ALICE.into()),
331
1
                para_id,
332
1
                get_genesis_data_with_validation_code().0,
333
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
334
1
            ));
335

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

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

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

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