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::{tests::common::*, ContainerRegistrar, Paras, ServicesPayment},
21
    cumulus_primitives_core::{relay_chain::HeadData, ParaId},
22
    frame_support::assert_ok,
23
    sp_std::vec,
24
};
25

            
26
#[test]
27
1
fn test_can_buy_credits_before_registering_para() {
28
1
    ExtBuilder::default()
29
1
        .with_balances(vec![
30
1
            // Alice gets 10k extra tokens for her mapping deposit
31
1
            (AccountId::from(ALICE), 210_000 * UNIT),
32
1
            (AccountId::from(BOB), 100_000 * UNIT),
33
1
            (AccountId::from(CHARLIE), 100_000 * UNIT),
34
1
            (AccountId::from(DAVE), 100_000 * UNIT),
35
1
        ])
36
1
        .with_collators(vec![
37
1
            (AccountId::from(ALICE), 210 * UNIT),
38
1
            (AccountId::from(BOB), 100 * UNIT),
39
1
            (AccountId::from(CHARLIE), 100 * UNIT),
40
1
            (AccountId::from(DAVE), 100 * UNIT),
41
1
        ])
42
1
        .build()
43
1
        .execute_with(|| {
44
1
            run_to_block(2);
45
1

            
46
1
            // Try to buy the maximum amount of credits
47
1
            let balance_before = System::account(AccountId::from(ALICE)).data.free;
48
1
            assert_ok!(ServicesPayment::purchase_credits(
49
1
                origin_of(ALICE.into()),
50
1
                1001.into(),
51
1
                block_credits_to_required_balance(u32::MAX, 1001.into())
52
1
            ));
53
1
            let balance_after = System::account(AccountId::from(ALICE)).data.free;
54
1

            
55
1
            // Now parachain tank should have this amount
56
1
            let balance_tank = System::account(ServicesPayment::parachain_tank(1001.into()))
57
1
                .data
58
1
                .free;
59
1

            
60
1
            assert_eq!(
61
1
                balance_tank,
62
1
                block_credits_to_required_balance(u32::MAX, 1001.into())
63
1
            );
64

            
65
1
            let expected_cost = block_credits_to_required_balance(u32::MAX, 1001.into());
66
1
            assert_eq!(balance_before - balance_after, expected_cost);
67
1
        });
68
1
}
69

            
70
#[test]
71
1
fn test_can_buy_credits_before_registering_para_and_receive_free_credits() {
72
1
    ExtBuilder::default()
73
1
        .with_balances(vec![
74
1
            // Alice gets 10k extra tokens for her mapping deposit
75
1
            (AccountId::from(ALICE), 210_000 * UNIT),
76
1
            (AccountId::from(BOB), 100_000 * UNIT),
77
1
            (AccountId::from(CHARLIE), 100_000 * UNIT),
78
1
            (AccountId::from(DAVE), 100_000 * UNIT),
79
1
        ])
80
1
        .with_collators(vec![
81
1
            (AccountId::from(ALICE), 210 * UNIT),
82
1
            (AccountId::from(BOB), 100 * UNIT),
83
1
            (AccountId::from(CHARLIE), 100 * UNIT),
84
1
            (AccountId::from(DAVE), 100 * UNIT),
85
1
        ])
86
1
        .build()
87
1
        .execute_with(|| {
88
1
            run_to_block(2);
89
1

            
90
1
            // Try to buy (FreeBlockProductionCredits - 1) credits
91
1
            let balance_before = System::account(AccountId::from(ALICE)).data.free;
92
1
            assert_ok!(ServicesPayment::purchase_credits(
93
1
                origin_of(ALICE.into()),
94
1
                1001.into(),
95
1
                block_credits_to_required_balance(
96
1
                    crate::FreeBlockProductionCredits::get() - 1,
97
1
                    1001.into()
98
1
                )
99
1
            ));
100
1
            let balance_after = System::account(AccountId::from(ALICE)).data.free;
101
1

            
102
1
            // Now parachain tank should have this amount
103
1
            let balance_tank = System::account(ServicesPayment::parachain_tank(1001.into()))
104
1
                .data
105
1
                .free;
106
1

            
107
1
            assert_eq!(
108
1
                balance_tank,
109
1
                block_credits_to_required_balance(
110
1
                    crate::FreeBlockProductionCredits::get() - 1,
111
1
                    1001.into()
112
1
                )
113
1
            );
114

            
115
1
            let expected_cost = block_credits_to_required_balance(
116
1
                crate::FreeBlockProductionCredits::get() - 1,
117
1
                1001.into(),
118
1
            );
119
1
            assert_eq!(balance_before - balance_after, expected_cost);
120

            
121
            // Now register para
122
1
            assert_ok!(ContainerRegistrar::register(
123
1
                origin_of(ALICE.into()),
124
1
                1001.into(),
125
1
                get_genesis_data_with_validation_code().0,
126
1
                Some(HeadData(vec![1u8, 2u8, 3u8]))
127
1
            ));
128

            
129
1
            run_to_session(2);
130
1

            
131
1
            // We need to accept the validation code, so that the para is onboarded after 2 sessions.
132
1
            assert_ok!(Paras::add_trusted_validation_code(
133
1
                root_origin(),
134
1
                get_genesis_data_with_validation_code().1.into()
135
1
            ));
136
1
            run_to_session(4);
137
1

            
138
1
            set_dummy_boot_node(origin_of(ALICE.into()), 1001.into());
139
1

            
140
1
            assert_ok!(ContainerRegistrar::mark_valid_for_collating(
141
1
                root_origin(),
142
1
                1001.into()
143
1
            ));
144

            
145
            // We received free credits, because we cannot have more than FreeBlockProductionCredits
146
1
            let credits =
147
1
                pallet_services_payment::BlockProductionCredits::<Runtime>::get(ParaId::from(1001))
148
1
                    .unwrap_or_default();
149
1
            assert_eq!(credits, crate::FreeBlockProductionCredits::get());
150
1
        });
151
1
}