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, Registrar, 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
                2000.into(),
51
1
                block_credits_to_required_balance(u32::MAX, 2000.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(2000.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, 2000.into())
63
1
            );
64

            
65
1
            let expected_cost = block_credits_to_required_balance(u32::MAX, 2000.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
                2000.into(),
95
1
                block_credits_to_required_balance(
96
1
                    crate::FreeBlockProductionCredits::get() - 1,
97
1
                    2000.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(2000.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
                    2000.into()
112
1
                )
113
1
            );
114

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

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

            
130
1
            run_to_session(2);
131
1

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

            
139
1
            set_dummy_boot_node(origin_of(ALICE.into()), 2000.into());
140
1

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

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