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 sp_runtime::traits::BadOrigin;
20
use {
21
    crate::{
22
        tests::common::*, Balances, CollatorConfiguration, ContainerRegistrar, DataPreservers,
23
        ForeignAssetsCreator, Registrar, StreamPayment,
24
    },
25
    alloc::vec,
26
    cumulus_primitives_core::{relay_chain::HeadData, ParaId},
27
    frame_support::{assert_err, assert_noop, assert_ok, BoundedVec},
28
    pallet_registrar_runtime_api::{
29
        runtime_decl_for_registrar_api::RegistrarApi, ContainerChainGenesisData,
30
    },
31
    pallet_stream_payment::StreamConfig,
32
    starlight_runtime_constants::currency::EXISTENTIAL_DEPOSIT,
33
    tp_stream_payment_common::{
34
        AssetId as StreamPaymentAssetId, TimeUnit as StreamPaymentTimeUnit,
35
    },
36
    xcm::latest::prelude::{Junctions::X2, *},
37
};
38

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

            
62
#[test]
63
1
fn genesis_para_registrar() {
64
1
    ExtBuilder::default()
65
1
        .with_empty_parachains(vec![1001, 1002])
66
1
        .build()
67
1
        .execute_with(|| {
68
1
            assert_eq!(
69
1
                ContainerRegistrar::registered_para_ids(),
70
1
                vec![1001.into(), 1002.into()]
71
            );
72
1
        });
73
1
}
74

            
75
#[test]
76
1
fn genesis_para_registrar_deregister() {
77
1
    ExtBuilder::default()
78
1
        .with_empty_parachains(vec![1001, 1002])
79
1
        .build()
80
1
        .execute_with(|| {
81
1
            assert_eq!(
82
1
                ContainerRegistrar::registered_para_ids(),
83
1
                vec![1001.into(), 1002.into()]
84
            );
85

            
86
1
            run_to_block(2);
87
1
            assert_ok!(
88
1
                ContainerRegistrar::deregister(root_origin(), 1002.into()),
89
                ()
90
            );
91

            
92
            // Pending
93
1
            assert_eq!(
94
1
                ContainerRegistrar::pending_registered_para_ids(),
95
1
                vec![(2u32, BoundedVec::try_from(vec![1001u32.into()]).unwrap())]
96
            );
97

            
98
1
            run_to_session(1);
99
1
            assert_eq!(
100
1
                ContainerRegistrar::pending_registered_para_ids(),
101
1
                vec![(2u32, BoundedVec::try_from(vec![1001u32.into()]).unwrap())]
102
            );
103
1
            assert_eq!(
104
1
                ContainerRegistrar::registered_para_ids(),
105
1
                vec![1001.into(), 1002.into()]
106
            );
107

            
108
1
            run_to_session(2);
109
1
            assert_eq!(ContainerRegistrar::pending_registered_para_ids(), vec![]);
110
1
            assert_eq!(ContainerRegistrar::registered_para_ids(), vec![1001.into()]);
111
1
        });
112
1
}
113

            
114
#[test]
115
1
fn genesis_para_registrar_runtime_api() {
116
1
    ExtBuilder::default()
117
1
        .with_empty_parachains(vec![1001, 1002])
118
1
        .build()
119
1
        .execute_with(|| {
120
1
            assert_eq!(
121
1
                ContainerRegistrar::registered_para_ids(),
122
1
                vec![1001.into(), 1002.into()]
123
            );
124
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into(), 1002.into()]);
125

            
126
1
            run_to_block(2);
127
1
            assert_ok!(
128
1
                ContainerRegistrar::deregister(root_origin(), 1002.into()),
129
                ()
130
            );
131
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into(), 1002.into()]);
132

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

            
140
1
            run_to_session(2);
141
1
            assert_eq!(ContainerRegistrar::registered_para_ids(), vec![1001.into()]);
142
1
            assert_eq!(Runtime::registered_paras(), vec![1001.into()]);
143
1
        });
144
1
}
145

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

            
183
1
            assert_eq!(
184
1
                Runtime::genesis_data(2001.into()).as_ref(),
185
1
                Some(&genesis_data_2001)
186
            );
187
1
            assert_eq!(
188
1
                Runtime::genesis_data(2002.into()).as_ref(),
189
1
                Some(&genesis_data_2002)
190
            );
191
1
            assert_eq!(Runtime::genesis_data(2003.into()).as_ref(), None);
192

            
193
1
            run_to_block(2);
194
1
            assert_ok!(ContainerRegistrar::deregister(root_origin(), 2002.into()), ());
195

            
196
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");
197
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
198
1
            assert_ok!(
199
1
                ContainerRegistrar::register(
200
1
                    origin_of(ALICE.into()),
201
1
                    2003.into(),
202
1
                    get_genesis_data_with_validation_code().0,
203
1
                    Some(HeadData(vec![1u8, 1u8, 1u8]))
204
                ),
205
                ()
206
            );
207

            
208
            // Registered container chains are inserted immediately
209
1
            assert_eq!(
210
1
                Runtime::genesis_data(2003.into()).as_ref(),
211
1
                Some(&get_genesis_data_with_validation_code().0)
212
            );
213

            
214
            // Deregistered container chain genesis data is removed after 2 sessions
215
1
            run_to_session(2u32);
216
1
            assert_eq!(Runtime::genesis_data(2002.into()).as_ref(), None);
217
1
        });
218
1
}
219

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

            
230
1
        assert_ok!(
231
1
            CollatorConfiguration::set_max_collators(root_origin(), 50),
232
            ()
233
        );
234
1
        run_to_session(1u32);
235

            
236
1
        assert_ok!(
237
1
            CollatorConfiguration::set_min_orchestrator_collators(root_origin(), 20),
238
            ()
239
        );
240
1
        assert_eq!(CollatorConfiguration::config().max_collators, 100);
241
1
        assert_eq!(
242
1
            CollatorConfiguration::config().min_orchestrator_collators,
243
            2
244
        );
245
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
246

            
247
1
        run_to_session(2u32);
248
1
        assert_ok!(
249
1
            CollatorConfiguration::set_collators_per_container(root_origin(), 10),
250
            ()
251
        );
252
1
        assert_eq!(CollatorConfiguration::config().max_collators, 50);
253
1
        assert_eq!(
254
1
            CollatorConfiguration::config().min_orchestrator_collators,
255
            2
256
        );
257
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
258

            
259
1
        run_to_session(3u32);
260

            
261
1
        assert_eq!(CollatorConfiguration::config().max_collators, 50);
262
1
        assert_eq!(
263
1
            CollatorConfiguration::config().min_orchestrator_collators,
264
            20
265
        );
266
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 2);
267

            
268
1
        run_to_session(4u32);
269

            
270
1
        assert_eq!(CollatorConfiguration::config().max_collators, 50);
271
1
        assert_eq!(
272
1
            CollatorConfiguration::config().min_orchestrator_collators,
273
            20
274
        );
275
1
        assert_eq!(CollatorConfiguration::config().collators_per_container, 10);
276
1
    });
277
1
}
278

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

            
312
#[test]
313
1
fn test_container_deregister_unassign_data_preserver() {
314
1
    ExtBuilder::default()
315
1
        .with_balances(vec![
316
1
            (AccountId::from(ALICE), 210_000 * UNIT),
317
1
            (AccountId::from(BOB), 100_000 * UNIT),
318
1
        ])
319
1
        .build()
320
1
        .execute_with(|| {
321
            use pallet_data_preservers::{
322
                AssignerParameterOf, NodeType, ParaIdsFilter, Profile, ProviderRequestOf,
323
            };
324

            
325
1
            let profile = Profile {
326
1
                bootnode_url: Some(b"test".to_vec().try_into().unwrap()),
327
1
                direct_rpc_urls: Default::default(),
328
1
                proxy_rpc_urls: Default::default(),
329
1
                para_ids: ParaIdsFilter::AnyParaId,
330
1
                node_type: NodeType::Substrate,
331
1
                additional_info: Default::default(),
332
1
                assignment_request: ProviderRequestOf::<Runtime>::Free,
333
1
            };
334

            
335
1
            let para_id = ParaId::from(2000);
336
1
            let profile_id = 0u64;
337
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
338
1
            assert_ok!(ContainerRegistrar::register(
339
1
                origin_of(ALICE.into()),
340
1
                para_id,
341
1
                get_genesis_data_with_validation_code().0,
342
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
343
            ));
344

            
345
1
            assert_ok!(DataPreservers::create_profile(
346
1
                origin_of(BOB.into()),
347
1
                profile.clone(),
348
            ));
349

            
350
            // Start assignment
351
1
            assert_ok!(DataPreservers::start_assignment(
352
1
                origin_of(ALICE.into()),
353
1
                profile_id,
354
1
                para_id,
355
1
                AssignerParameterOf::<Runtime>::Free
356
            ));
357
1
            assert!(pallet_data_preservers::Assignments::<Runtime>::get(para_id).contains(&0u64));
358

            
359
            // Deregister from Registrar
360
1
            assert_ok!(ContainerRegistrar::deregister(root_origin(), para_id), ());
361

            
362
            // Check DataPreserver assignment has been cleared
363
1
            assert!(pallet_data_preservers::Assignments::<Runtime>::get(para_id).is_empty());
364
1
        });
365
1
}
366

            
367
#[test]
368
1
fn stream_payment_works() {
369
1
    ExtBuilder::default()
370
1
        .with_balances(vec![
371
1
            (AccountId::from(ALICE), 100_000 * UNIT),
372
1
            (AccountId::from(BOB), 100_000 * UNIT),
373
1
            (AccountId::from(CHARLIE), 100_000 * UNIT),
374
1
        ])
375
1
        .with_collators(vec![
376
1
            (AccountId::from(CHARLIE), 100 * UNIT),
377
1
            (AccountId::from(DAVE), 100 * UNIT),
378
1
        ])
379
1
        .build()
380
1
        .execute_with(|| {
381
            use pallet_stream_payment::{ChangeKind, StreamConfig};
382

            
383
1
            assert_ok!(StreamPayment::open_stream(
384
1
                origin_of(ALICE.into()),
385
1
                BOB.into(),
386
1
                StreamConfig {
387
1
                    rate: 2 * UNIT,
388
1
                    asset_id: StreamPaymentAssetId::Native,
389
1
                    time_unit: StreamPaymentTimeUnit::BlockNumber,
390
1
                    minimum_request_deadline_delay: 0,
391
1
                    soft_minimum_deposit: 0,
392
1
                },
393
1
                1_000 * UNIT,
394
            ));
395

            
396
1
            run_block();
397

            
398
1
            assert_ok!(StreamPayment::perform_payment(origin_of(CHARLIE.into()), 0));
399
1
            assert_eq!(
400
1
                Balances::free_balance(AccountId::from(BOB)),
401
                100_000 * UNIT + 2 * UNIT
402
            );
403

            
404
1
            assert_ok!(StreamPayment::request_change(
405
1
                origin_of(ALICE.into()),
406
                0,
407
1
                ChangeKind::Suggestion,
408
1
                StreamConfig {
409
1
                    rate: 1 * UNIT,
410
1
                    asset_id: StreamPaymentAssetId::Native,
411
1
                    time_unit: StreamPaymentTimeUnit::BlockNumber,
412
1
                    minimum_request_deadline_delay: 0,
413
1
                    soft_minimum_deposit: 0,
414
1
                },
415
1
                None,
416
            ));
417

            
418
1
            assert_ok!(StreamPayment::accept_requested_change(
419
1
                origin_of(BOB.into()),
420
                0,
421
                1, // nonce
422
1
                None,
423
            ));
424

            
425
1
            run_block();
426

            
427
1
            assert_ok!(StreamPayment::close_stream(origin_of(BOB.into()), 0));
428

            
429
1
            assert_eq!(
430
1
                Balances::free_balance(AccountId::from(BOB)),
431
                100_000 * UNIT + 3 * UNIT
432
            );
433
1
            assert_eq!(
434
1
                Balances::free_balance(AccountId::from(ALICE)),
435
                100_000 * UNIT - 3 * UNIT
436
            );
437
1
        });
438
1
}
439

            
440
#[test]
441
1
fn test_data_preserver_with_stream_payment() {
442
1
    ExtBuilder::default()
443
1
        .with_balances(vec![
444
1
            (AccountId::from(ALICE), 210_000 * UNIT),
445
1
            (AccountId::from(BOB), 100_000 * UNIT),
446
1
        ])
447
1
        .build()
448
1
        .execute_with(|| {
449
            use pallet_data_preservers::{
450
                AssignerParameterOf, NodeType, ParaIdsFilter, Profile, ProviderRequestOf,
451
            };
452

            
453
1
            let profile = Profile {
454
1
                bootnode_url: Some(b"test".to_vec().try_into().unwrap()),
455
1
                direct_rpc_urls: Default::default(),
456
1
                proxy_rpc_urls: Default::default(),
457
1
                para_ids: ParaIdsFilter::AnyParaId,
458
1
                node_type: NodeType::Substrate,
459
1
                additional_info: Default::default(),
460
1
                assignment_request: ProviderRequestOf::<Runtime>::StreamPayment {
461
1
                    config: StreamConfig {
462
1
                        time_unit: StreamPaymentTimeUnit::BlockNumber,
463
1
                        asset_id: StreamPaymentAssetId::Native,
464
1
                        rate: 42,
465
1
                        minimum_request_deadline_delay: 0,
466
1
                        soft_minimum_deposit: 0,
467
1
                    },
468
1
                },
469
1
            };
470

            
471
1
            let para_id = ParaId::from(2000);
472
1
            let profile_id = 0u64;
473

            
474
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
475
1
            assert_ok!(ContainerRegistrar::register(
476
1
                origin_of(ALICE.into()),
477
1
                para_id,
478
1
                get_genesis_data_with_validation_code().0,
479
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
480
            ));
481

            
482
1
            assert_ok!(DataPreservers::create_profile(
483
1
                origin_of(BOB.into()),
484
1
                profile.clone(),
485
            ));
486

            
487
            // Start assignment
488
1
            assert_ok!(DataPreservers::start_assignment(
489
1
                origin_of(ALICE.into()),
490
1
                profile_id,
491
1
                para_id,
492
1
                AssignerParameterOf::<Runtime>::StreamPayment {
493
1
                    initial_deposit: 1_000
494
1
                }
495
            ));
496
1
            assert!(
497
1
                pallet_data_preservers::Assignments::<Runtime>::get(para_id).contains(&profile_id)
498
            );
499
1
            let profile = pallet_data_preservers::Profiles::<Runtime>::get(profile_id)
500
1
                .expect("profile to exists");
501
1
            let (assigned_para_id, witness) = profile.assignment.expect("profile to be assigned");
502
1
            assert_eq!(assigned_para_id, para_id);
503
1
            assert_eq!(
504
                witness,
505
                tp_data_preservers_common::AssignmentWitness::StreamPayment { stream_id: 0 }
506
            );
507
1
        });
508
1
}
509

            
510
#[test]
511
1
fn test_data_preserver_kind_needs_to_match() {
512
1
    ExtBuilder::default()
513
1
        .with_balances(vec![
514
1
            (AccountId::from(ALICE), 210_000 * UNIT),
515
1
            (AccountId::from(BOB), 100_000 * UNIT),
516
1
        ])
517
1
        .build()
518
1
        .execute_with(|| {
519
            use pallet_data_preservers::{
520
                AssignerParameterOf, NodeType, ParaIdsFilter, Profile, ProviderRequestOf,
521
            };
522

            
523
1
            let profile = Profile {
524
1
                bootnode_url: Some(b"test".to_vec().try_into().unwrap()),
525
1
                direct_rpc_urls: Default::default(),
526
1
                proxy_rpc_urls: Default::default(),
527
1
                para_ids: ParaIdsFilter::AnyParaId,
528
1
                node_type: NodeType::Substrate,
529
1
                additional_info: Default::default(),
530
1
                assignment_request: ProviderRequestOf::<Runtime>::Free,
531
1
            };
532

            
533
1
            let para_id = ParaId::from(2000);
534
1
            let profile_id = 0u64;
535

            
536
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
537
1
            assert_ok!(ContainerRegistrar::register(
538
1
                origin_of(ALICE.into()),
539
1
                para_id,
540
1
                get_genesis_data_with_validation_code().0,
541
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
542
            ));
543

            
544
1
            assert_ok!(DataPreservers::create_profile(
545
1
                origin_of(BOB.into()),
546
1
                profile.clone(),
547
            ));
548

            
549
            // Start assignment
550
1
            assert_err!(
551
1
                DataPreservers::start_assignment(
552
1
                    origin_of(ALICE.into()),
553
1
                    profile_id,
554
1
                    para_id,
555
1
                    AssignerParameterOf::<Runtime>::StreamPayment {
556
1
                        initial_deposit: 1_000
557
1
                    }
558
                ),
559
1
                pallet_data_preservers::Error::<Runtime>::AssignmentPaymentRequestParameterMismatch
560
            );
561
1
        });
562
1
}
563

            
564
#[test]
565
1
fn test_registrar_extrinsic_permissions() {
566
1
    ExtBuilder::default()
567
1
        .with_balances(vec![
568
1
            (AccountId::from(ALICE), 210_000 * UNIT),
569
1
            (AccountId::from(BOB), 100_000 * UNIT),
570
1
        ])
571
1
        .with_empty_parachains(vec![1001])
572
1
        .build()
573
1
        .execute_with(|| {
574
1
            let para_id = ParaId::from(1001);
575

            
576
            // Pause container chain should fail if not para manager
577
1
            assert_noop!(
578
1
                ContainerRegistrar::pause_container_chain(origin_of(BOB.into()), para_id),
579
1
                BadOrigin
580
            );
581

            
582
            // Set Bob as para manager
583
1
            assert_ok!(ContainerRegistrar::set_para_manager(
584
1
                root_origin(),
585
1
                para_id,
586
1
                AccountId::from(BOB)
587
            ));
588

            
589
            // Pause container chain should succeed if para manager
590
1
            assert_ok!(
591
1
                ContainerRegistrar::pause_container_chain(origin_of(BOB.into()), para_id),
592
                ()
593
            );
594
1
        });
595
1
}
596

            
597
#[test]
598
1
fn stream_payment_stored_profile_correct_size() {
599
    use crate::OPEN_STREAM_HOLD_AMOUNT;
600
    use pallet_stream_payment::{
601
        ChangeKind, ChangeRequest, DepositChange, Party, Stream, StreamConfig, StreamOf,
602
    };
603
    use parity_scale_codec::Encode;
604

            
605
1
    let stream: StreamOf<Runtime> = Stream {
606
1
        source: ALICE.into(),
607
1
        target: BOB.into(),
608
1
        config: StreamConfig {
609
1
            time_unit: StreamPaymentTimeUnit::Timestamp,
610
1
            asset_id: StreamPaymentAssetId::Native,
611
1
            rate: 41,
612
1
            minimum_request_deadline_delay: 0,
613
1
            soft_minimum_deposit: 0,
614
1
        },
615
1
        deposit: 42,
616
1
        last_time_updated: 43,
617
1
        request_nonce: 44,
618
1
        pending_request: Some(ChangeRequest {
619
1
            requester: Party::Source,
620
1
            kind: ChangeKind::Mandatory { deadline: 45 },
621
1
            new_config: StreamConfig {
622
1
                time_unit: StreamPaymentTimeUnit::BlockNumber,
623
1
                asset_id: StreamPaymentAssetId::Native,
624
1
                rate: 46,
625
1
                minimum_request_deadline_delay: 0,
626
1
                soft_minimum_deposit: 0,
627
1
            },
628
1
            deposit_change: Some(DepositChange::Absolute(47)),
629
1
        }),
630
1
        opening_deposit: 48,
631
1
    };
632
1
    let size = stream.encoded_size();
633
1
    assert_eq!(
634
        size, OPEN_STREAM_HOLD_AMOUNT as usize,
635
        "encoded len doesn't match size configured for hold"
636
    );
637
1
}
638

            
639
#[test]
640
1
fn test_register_eth_foreign_asset() {
641
1
    ExtBuilder::default()
642
1
        .with_balances(vec![
643
1
            (AccountId::from(ALICE), 210_000 * UNIT),
644
1
            (AccountId::from(BOB), 100_000 * UNIT),
645
1
        ])
646
1
        .build()
647
1
        .execute_with(|| {
648
1
            let asset_location = Location {
649
1
                parents: 0,
650
1
                interior: X2([
651
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
652
1
                    AccountKey20 {
653
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
654
1
                        key: [0; 20],
655
1
                    },
656
1
                ]
657
1
                .into()),
658
1
            };
659

            
660
1
            let asset_id = 42u16;
661

            
662
1
            assert_ok!(ForeignAssetsCreator::create_foreign_asset(
663
1
                root_origin(),
664
1
                asset_location,
665
1
                asset_id,
666
1
                AccountId::from(BOB),
667
                true,
668
                1
669
            ));
670
1
        });
671
1
}
672

            
673
#[test]
674
1
fn test_register_eth_foreign_asset_not_root_should_fail() {
675
1
    ExtBuilder::default()
676
1
        .with_balances(vec![
677
1
            (AccountId::from(ALICE), 210_000 * UNIT),
678
1
            (AccountId::from(BOB), 100_000 * UNIT),
679
1
        ])
680
1
        .build()
681
1
        .execute_with(|| {
682
1
            let asset_location = Location {
683
1
                parents: 0,
684
1
                interior: X2([
685
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
686
1
                    AccountKey20 {
687
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
688
1
                        key: [0; 20],
689
1
                    },
690
1
                ]
691
1
                .into()),
692
1
            };
693

            
694
1
            let asset_id = 42u16;
695

            
696
1
            assert_noop!(
697
1
                ForeignAssetsCreator::create_foreign_asset(
698
1
                    origin_of(AccountId::from(ALICE)),
699
1
                    asset_location,
700
1
                    asset_id,
701
1
                    AccountId::from(BOB),
702
                    true,
703
                    1
704
                ),
705
1
                BadOrigin
706
            );
707
1
        });
708
1
}
709

            
710
#[test]
711
1
fn test_register_same_eth_foreign_asset_twice_should_fail() {
712
1
    ExtBuilder::default()
713
1
        .with_balances(vec![
714
1
            (AccountId::from(ALICE), 210_000 * UNIT),
715
1
            (AccountId::from(BOB), 100_000 * UNIT),
716
1
        ])
717
1
        .build()
718
1
        .execute_with(|| {
719
1
            let asset_location = Location {
720
1
                parents: 0,
721
1
                interior: X2([
722
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
723
1
                    AccountKey20 {
724
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
725
1
                        key: [0; 20],
726
1
                    },
727
1
                ]
728
1
                .into()),
729
1
            };
730

            
731
1
            let asset_id = 42u16;
732

            
733
1
            assert_ok!(ForeignAssetsCreator::create_foreign_asset(
734
1
                root_origin(),
735
1
                asset_location,
736
1
                asset_id,
737
1
                AccountId::from(BOB),
738
                true,
739
                1
740
            ));
741

            
742
1
            let asset_location = Location {
743
1
                parents: 0,
744
1
                interior: X2([
745
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
746
1
                    AccountKey20 {
747
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
748
1
                        key: [1; 20],
749
1
                    },
750
1
                ]
751
1
                .into()),
752
1
            };
753

            
754
1
            assert_noop!(
755
1
                ForeignAssetsCreator::create_foreign_asset(
756
1
                    root_origin(),
757
1
                    asset_location,
758
1
                    asset_id,
759
1
                    AccountId::from(BOB),
760
                    true,
761
                    1
762
                ),
763
1
                pallet_foreign_asset_creator::Error::<Runtime>::AssetAlreadyExists
764
            );
765
1
        });
766
1
}