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
        Registrar, StreamPayment,
24
    },
25
    cumulus_primitives_core::{relay_chain::HeadData, ParaId},
26
    frame_support::{assert_err, assert_noop, assert_ok, BoundedVec},
27
    pallet_registrar_runtime_api::{
28
        runtime_decl_for_registrar_api::RegistrarApi, ContainerChainGenesisData,
29
    },
30
    pallet_stream_payment::StreamConfig,
31
    sp_std::vec,
32
    starlight_runtime_constants::currency::EXISTENTIAL_DEPOSIT,
33
    tp_stream_payment_common::{
34
        AssetId as StreamPaymentAssetId, TimeUnit as StreamPaymentTimeUnit,
35
    },
36
};
37

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

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

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

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

            
91
            // Pending
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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
258
1
        run_to_session(3u32);
259
1

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

            
267
1
        run_to_session(4u32);
268
1

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

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

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

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

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

            
341
1
            assert_ok!(DataPreservers::create_profile(
342
1
                origin_of(BOB.into()),
343
1
                profile.clone(),
344
1
            ));
345

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

            
355
            // Deregister from Registrar
356
1
            assert_ok!(ContainerRegistrar::deregister(root_origin(), para_id), ());
357

            
358
            // Check DataPreserver assignment has been cleared
359
1
            assert!(pallet_data_preservers::Assignments::<Runtime>::get(para_id).is_empty());
360
1
        });
361
1
}
362

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

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

            
392
1
            run_block();
393
1

            
394
1
            assert_ok!(StreamPayment::perform_payment(origin_of(CHARLIE.into()), 0));
395
1
            assert_eq!(
396
1
                Balances::free_balance(AccountId::from(BOB)),
397
1
                100_000 * UNIT + 2 * UNIT
398
1
            );
399

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

            
414
1
            assert_ok!(StreamPayment::accept_requested_change(
415
1
                origin_of(BOB.into()),
416
1
                0,
417
1
                1, // nonce
418
1
                None,
419
1
            ));
420

            
421
1
            run_block();
422
1

            
423
1
            assert_ok!(StreamPayment::close_stream(origin_of(BOB.into()), 0));
424

            
425
1
            assert_eq!(
426
1
                Balances::free_balance(AccountId::from(BOB)),
427
1
                100_000 * UNIT + 3 * UNIT
428
1
            );
429
1
            assert_eq!(
430
1
                Balances::free_balance(AccountId::from(ALICE)),
431
1
                100_000 * UNIT - 3 * UNIT
432
1
            );
433
1
        });
434
1
}
435

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

            
449
1
            let profile = Profile {
450
1
                url: b"test".to_vec().try_into().unwrap(),
451
1
                para_ids: ParaIdsFilter::AnyParaId,
452
1
                mode: ProfileMode::Bootnode,
453
1
                assignment_request: ProviderRequestOf::<Runtime>::StreamPayment {
454
1
                    config: StreamConfig {
455
1
                        time_unit: StreamPaymentTimeUnit::BlockNumber,
456
1
                        asset_id: StreamPaymentAssetId::Native,
457
1
                        rate: 42,
458
1
                        minimum_request_deadline_delay: 0,
459
1
                        soft_minimum_deposit: 0,
460
1
                    },
461
1
                },
462
1
            };
463
1

            
464
1
            let para_id = ParaId::from(2000);
465
1
            let profile_id = 0u64;
466
1

            
467
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
468
1
            assert_ok!(ContainerRegistrar::register(
469
1
                origin_of(ALICE.into()),
470
1
                para_id,
471
1
                get_genesis_data_with_validation_code().0,
472
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
473
1
            ));
474

            
475
1
            assert_ok!(DataPreservers::create_profile(
476
1
                origin_of(BOB.into()),
477
1
                profile.clone(),
478
1
            ));
479

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

            
503
#[test]
504
1
fn test_data_preserver_kind_needs_to_match() {
505
1
    ExtBuilder::default()
506
1
        .with_balances(vec![
507
1
            (AccountId::from(ALICE), 210_000 * UNIT),
508
1
            (AccountId::from(BOB), 100_000 * UNIT),
509
1
        ])
510
1
        .build()
511
1
        .execute_with(|| {
512
            use pallet_data_preservers::{
513
                AssignerParameterOf, ParaIdsFilter, Profile, ProfileMode, ProviderRequestOf,
514
            };
515

            
516
1
            let profile = Profile {
517
1
                url: b"test".to_vec().try_into().unwrap(),
518
1
                para_ids: ParaIdsFilter::AnyParaId,
519
1
                mode: ProfileMode::Bootnode,
520
1
                assignment_request: ProviderRequestOf::<Runtime>::Free,
521
1
            };
522
1

            
523
1
            let para_id = ParaId::from(2000);
524
1
            let profile_id = 0u64;
525
1

            
526
1
            assert_ok!(Registrar::reserve(origin_of(ALICE.into())));
527
1
            assert_ok!(ContainerRegistrar::register(
528
1
                origin_of(ALICE.into()),
529
1
                para_id,
530
1
                get_genesis_data_with_validation_code().0,
531
1
                Some(HeadData(vec![1u8, 1u8, 1u8]))
532
1
            ));
533

            
534
1
            assert_ok!(DataPreservers::create_profile(
535
1
                origin_of(BOB.into()),
536
1
                profile.clone(),
537
1
            ));
538

            
539
            // Start assignment
540
1
            assert_err!(
541
1
                DataPreservers::start_assignment(
542
1
                    origin_of(ALICE.into()),
543
1
                    profile_id,
544
1
                    para_id,
545
1
                    AssignerParameterOf::<Runtime>::StreamPayment {
546
1
                        initial_deposit: 1_000
547
1
                    }
548
1
                ),
549
1
                pallet_data_preservers::Error::<Runtime>::AssignmentPaymentRequestParameterMismatch
550
1
            );
551
1
        });
552
1
}
553

            
554
#[test]
555
1
fn test_registrar_extrinsic_permissions() {
556
1
    ExtBuilder::default()
557
1
        .with_balances(vec![
558
1
            (AccountId::from(ALICE), 210_000 * UNIT),
559
1
            (AccountId::from(BOB), 100_000 * UNIT),
560
1
        ])
561
1
        .with_empty_parachains(vec![1001])
562
1
        .build()
563
1
        .execute_with(|| {
564
1
            let para_id = ParaId::from(1001);
565
1

            
566
1
            // Pause container chain should fail if not para manager
567
1
            assert_noop!(
568
1
                ContainerRegistrar::pause_container_chain(origin_of(BOB.into()), para_id),
569
1
                BadOrigin
570
1
            );
571

            
572
            // Set Bob as para manager
573
1
            assert_ok!(ContainerRegistrar::set_para_manager(
574
1
                root_origin(),
575
1
                para_id,
576
1
                AccountId::from(BOB)
577
1
            ));
578

            
579
            // Pause container chain should succeed if para manager
580
            // TODO: Revert later after allowed this operation to para manager
581
            // assert_ok!(
582
            //     ContainerRegistrar::pause_container_chain(origin_of(BOB.into()), para_id),
583
            //     ()
584
            // );
585
1
        });
586
1
}
587

            
588
#[test]
589
1
fn stream_payment_stored_profile_correct_size() {
590
    use crate::OPEN_STREAM_HOLD_AMOUNT;
591
    use pallet_stream_payment::{
592
        ChangeKind, ChangeRequest, DepositChange, Party, Stream, StreamConfig, StreamOf,
593
    };
594
    use parity_scale_codec::Encode;
595

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