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, RuntimeEvent, StreamPayment,
24
    },
25
    alloc::vec,
26
    cumulus_primitives_core::{relay_chain::HeadData, ParaId},
27
    dancelight_runtime_constants::currency::EXISTENTIAL_DEPOSIT,
28
    frame_support::{assert_err, assert_noop, assert_ok, BoundedVec},
29
    pallet_foreign_asset_creator::{AssetIdToForeignAsset, ForeignAssetToAssetId},
30
    pallet_registrar_runtime_api::{
31
        runtime_decl_for_registrar_api::RegistrarApi, ContainerChainGenesisData,
32
    },
33
    pallet_stream_payment::StreamConfig,
34
    tp_stream_payment_common::{
35
        AssetId as StreamPaymentAssetId, TimeUnit as StreamPaymentTimeUnit,
36
    },
37
    xcm::latest::prelude::{Junctions::X2, *},
38
};
39

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
260
1
        run_to_session(3u32);
261

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

            
269
1
        run_to_session(4u32);
270

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

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

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

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

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

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

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

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

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

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

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

            
397
1
            run_block();
398

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

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

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

            
426
1
            run_block();
427

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
661
1
            let asset_id = 42u16;
662

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

            
672
1
            let foreign_asset_created_event = System::events()
673
1
                .iter()
674
2
                .filter(|r| {
675
1
                    matches!(
676
1
                        r.event,
677
                        RuntimeEvent::ForeignAssetsCreator(
678
                            pallet_foreign_asset_creator::Event::ForeignAssetCreated { .. },
679
                        )
680
                    )
681
2
                })
682
1
                .count();
683

            
684
1
            assert_eq!(
685
                foreign_asset_created_event, 1,
686
                "ForeignAssetCreated event should be emitted!"
687
            );
688

            
689
1
            assert_eq!(
690
1
                AssetIdToForeignAsset::<Runtime>::get(asset_id),
691
1
                Some(asset_location.clone())
692
            );
693

            
694
1
            assert_eq!(
695
1
                ForeignAssetToAssetId::<Runtime>::get(asset_location.clone()),
696
1
                Some(asset_id)
697
            );
698
1
        });
699
1
}
700

            
701
#[test]
702
1
fn test_register_eth_foreign_asset_not_root_should_fail() {
703
1
    ExtBuilder::default()
704
1
        .with_balances(vec![
705
1
            (AccountId::from(ALICE), 210_000 * UNIT),
706
1
            (AccountId::from(BOB), 100_000 * UNIT),
707
1
        ])
708
1
        .build()
709
1
        .execute_with(|| {
710
1
            let asset_location = Location {
711
1
                parents: 1,
712
1
                interior: X2([
713
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
714
1
                    AccountKey20 {
715
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
716
1
                        key: [0; 20],
717
1
                    },
718
1
                ]
719
1
                .into()),
720
1
            };
721

            
722
1
            let asset_id = 42u16;
723

            
724
1
            assert_noop!(
725
1
                ForeignAssetsCreator::create_foreign_asset(
726
1
                    origin_of(AccountId::from(ALICE)),
727
1
                    asset_location,
728
1
                    asset_id,
729
1
                    AccountId::from(BOB),
730
                    true,
731
                    1
732
                ),
733
1
                BadOrigin
734
            );
735
1
        });
736
1
}
737

            
738
#[test]
739
1
fn test_register_same_eth_foreign_asset_twice_should_fail() {
740
1
    ExtBuilder::default()
741
1
        .with_balances(vec![
742
1
            (AccountId::from(ALICE), 210_000 * UNIT),
743
1
            (AccountId::from(BOB), 100_000 * UNIT),
744
1
        ])
745
1
        .build()
746
1
        .execute_with(|| {
747
1
            let asset_location = Location {
748
1
                parents: 1,
749
1
                interior: X2([
750
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
751
1
                    AccountKey20 {
752
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
753
1
                        key: [0; 20],
754
1
                    },
755
1
                ]
756
1
                .into()),
757
1
            };
758

            
759
1
            let asset_id = 42u16;
760

            
761
1
            assert_ok!(ForeignAssetsCreator::create_foreign_asset(
762
1
                root_origin(),
763
1
                asset_location,
764
1
                asset_id,
765
1
                AccountId::from(BOB),
766
                true,
767
                1
768
            ));
769

            
770
1
            let asset_location = Location {
771
1
                parents: 1,
772
1
                interior: X2([
773
1
                    GlobalConsensus(NetworkId::Ethereum { chain_id: 1 }),
774
1
                    AccountKey20 {
775
1
                        network: Some(NetworkId::Ethereum { chain_id: 1 }),
776
1
                        key: [1; 20],
777
1
                    },
778
1
                ]
779
1
                .into()),
780
1
            };
781

            
782
1
            assert_noop!(
783
1
                ForeignAssetsCreator::create_foreign_asset(
784
1
                    root_origin(),
785
1
                    asset_location,
786
1
                    asset_id,
787
1
                    AccountId::from(BOB),
788
                    true,
789
                    1
790
                ),
791
1
                pallet_foreign_asset_creator::Error::<Runtime>::AssetAlreadyExists
792
            );
793
1
        });
794
1
}