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
use {super::*, crate::EnableMarkingOffline};
18
5
fn make_collator_inactive(collator: AccountId) {
19
5
    run_to_block(u64::from(get_max_inactive_sessions()) * 5u64);
20
10
    for session_index in 0..get_max_inactive_sessions() {
21
10
        InactiveCollators::<Test>::insert(session_index, get_collator_set(vec![collator]));
22
10
    }
23
5
}
24
#[test]
25
1
fn enabling_and_disabling_offline_marking_works() {
26
1
    ExtBuilder.build().execute_with(|| {
27
1
        assert!(!EnableMarkingOffline::<Test>::get());
28
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
29
1
            RuntimeOrigin::root(),
30
1
            true
31
1
        ));
32
1
        assert!(EnableMarkingOffline::<Test>::get());
33
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
34
1
            RuntimeOrigin::root(),
35
1
            false
36
1
        ));
37
1
        assert!(!EnableMarkingOffline::<Test>::get());
38
1
    });
39
1
}
40

            
41
#[test]
42
1
fn enabling_and_disabling_offline_marking_fails_for_non_root() {
43
1
    ExtBuilder.build().execute_with(|| {
44
1
        assert_noop!(
45
1
            Pallet::<Test>::enable_offline_marking(RuntimeOrigin::signed(COLLATOR_1), true),
46
1
            BadOrigin
47
1
        );
48
1
    });
49
1
}
50
#[test]
51
1
fn set_offline_works() {
52
1
    ExtBuilder.build().execute_with(|| {
53
1
        assert!(!OfflineCollators::<Test>::get(COLLATOR_1));
54
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
55
1
            RuntimeOrigin::root(),
56
1
            true
57
1
        ));
58
1
        assert_ok!(Pallet::<Test>::set_offline(RuntimeOrigin::signed(
59
1
            COLLATOR_1
60
1
        )));
61
1
        System::assert_last_event(
62
1
            Event::CollatorStatusUpdated {
63
1
                collator: COLLATOR_1,
64
1
                is_offline: true,
65
1
            }
66
1
            .into(),
67
1
        );
68
1
        assert!(OfflineCollators::<Test>::get(COLLATOR_1));
69
1
    });
70
1
}
71
#[test]
72
1
fn set_offline_fails_if_offline_marking_is_not_enabled() {
73
1
    ExtBuilder.build().execute_with(|| {
74
1
        assert_noop!(
75
1
            Pallet::<Test>::set_offline(RuntimeOrigin::signed(COLLATOR_1)),
76
1
            Error::<Test>::MarkingOfflineNotEnabled
77
1
        );
78
1
    });
79
1
}
80
#[test]
81
1
fn set_offline_fails_if_collator_is_not_in_eligible_candidates() {
82
1
    ExtBuilder.build().execute_with(|| {
83
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
84
1
            RuntimeOrigin::root(),
85
1
            true
86
1
        ));
87
1
        assert_noop!(
88
1
            Pallet::<Test>::set_offline(RuntimeOrigin::signed(COLLATOR_3)),
89
1
            Error::<Test>::CollatorNotEligibleCandidate
90
1
        );
91
1
    });
92
1
}
93

            
94
#[test]
95
1
fn set_offline_fails_for_offline_collators() {
96
1
    ExtBuilder.build().execute_with(|| {
97
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
98
1
            RuntimeOrigin::root(),
99
1
            true
100
1
        ));
101
1
        OfflineCollators::<Test>::insert(COLLATOR_1, true);
102
1
        assert!(OfflineCollators::<Test>::get(COLLATOR_1));
103
1
        assert_noop!(
104
1
            Pallet::<Test>::set_offline(RuntimeOrigin::signed(COLLATOR_1)),
105
1
            Error::<Test>::CollatorNotOnline
106
1
        );
107
1
    });
108
1
}
109

            
110
#[test]
111
1
fn set_offline_fails_if_collator_is_invulnerable() {
112
1
    ExtBuilder.build().execute_with(|| {
113
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
114
1
            RuntimeOrigin::root(),
115
1
            true
116
1
        ));
117
1
        assert_noop!(
118
1
            Pallet::<Test>::set_offline(RuntimeOrigin::signed(COLLATOR_2)),
119
1
            Error::<Test>::MarkingInvulnerableOfflineInvalid
120
1
        );
121
1
    });
122
1
}
123

            
124
#[test]
125
1
fn set_online_works() {
126
1
    ExtBuilder.build().execute_with(|| {
127
1
        OfflineCollators::<Test>::insert(COLLATOR_1, true);
128
1
        assert!(OfflineCollators::<Test>::get(COLLATOR_1));
129
1
        assert_ok!(Pallet::<Test>::set_online(RuntimeOrigin::signed(
130
1
            COLLATOR_1
131
1
        )));
132
1
        System::assert_last_event(
133
1
            Event::CollatorStatusUpdated {
134
1
                collator: COLLATOR_1,
135
1
                is_offline: false,
136
1
            }
137
1
            .into(),
138
1
        );
139
1
        assert!(!OfflineCollators::<Test>::get(COLLATOR_1));
140
1
    });
141
1
}
142

            
143
#[test]
144
1
fn set_online_fails_for_online_collators() {
145
1
    ExtBuilder.build().execute_with(|| {
146
1
        assert!(!OfflineCollators::<Test>::get(COLLATOR_1));
147
1
        assert_noop!(
148
1
            Pallet::<Test>::set_online(RuntimeOrigin::signed(COLLATOR_1)),
149
1
            Error::<Test>::CollatorNotOffline
150
1
        );
151
1
    });
152
1
}
153

            
154
#[test]
155
1
fn notify_inactive_collator_works() {
156
1
    ExtBuilder.build().execute_with(|| {
157
1
        make_collator_inactive(COLLATOR_1);
158
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
159
1
            RuntimeOrigin::root(),
160
1
            true
161
1
        ));
162
1
        assert!(!OfflineCollators::<Test>::get(COLLATOR_1));
163
1
        assert_ok!(Pallet::<Test>::notify_inactive_collator(
164
1
            RuntimeOrigin::signed(COLLATOR_3),
165
1
            COLLATOR_1
166
1
        ));
167
1
        System::assert_last_event(
168
1
            Event::CollatorStatusUpdated {
169
1
                collator: COLLATOR_1,
170
1
                is_offline: true,
171
1
            }
172
1
            .into(),
173
1
        );
174
1
        assert!(OfflineCollators::<Test>::get(COLLATOR_1));
175
1
    });
176
1
}
177

            
178
#[test]
179
1
fn notify_inactive_collator_fails_if_collator_is_active() {
180
1
    ExtBuilder.build().execute_with(|| {
181
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
182
1
            RuntimeOrigin::root(),
183
1
            true
184
1
        ));
185
1
        assert_noop!(
186
1
            Pallet::<Test>::notify_inactive_collator(RuntimeOrigin::signed(COLLATOR_3), COLLATOR_1),
187
1
            Error::<Test>::CollatorCannotBeNotifiedAsInactive
188
1
        );
189
1
    });
190
1
}
191

            
192
#[test]
193
1
fn notify_inactive_collator_fails_if_offline_marking_is_not_enabled() {
194
1
    ExtBuilder.build().execute_with(|| {
195
1
        make_collator_inactive(COLLATOR_1);
196
1
        assert_noop!(
197
1
            Pallet::<Test>::notify_inactive_collator(RuntimeOrigin::signed(COLLATOR_3), COLLATOR_1),
198
1
            Error::<Test>::MarkingOfflineNotEnabled
199
1
        );
200
1
    });
201
1
}
202

            
203
#[test]
204
1
fn notify_inactive_collator_fails_for_collator_not_in_sorted_eligible_collators() {
205
1
    ExtBuilder.build().execute_with(|| {
206
1
        make_collator_inactive(COLLATOR_3);
207
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
208
1
            RuntimeOrigin::root(),
209
1
            true
210
1
        ));
211
1
        assert_noop!(
212
1
            Pallet::<Test>::notify_inactive_collator(RuntimeOrigin::signed(COLLATOR_2), COLLATOR_3),
213
1
            Error::<Test>::CollatorNotEligibleCandidate
214
1
        );
215
1
    });
216
1
}
217

            
218
#[test]
219
1
fn notify_inactive_collator_fails_for_offline_collators() {
220
1
    ExtBuilder.build().execute_with(|| {
221
1
        make_collator_inactive(COLLATOR_1);
222
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
223
1
            RuntimeOrigin::root(),
224
1
            true
225
1
        ));
226
1
        OfflineCollators::<Test>::insert(COLLATOR_1, true);
227
1
        assert!(OfflineCollators::<Test>::get(COLLATOR_1));
228
1
        assert_noop!(
229
1
            Pallet::<Test>::notify_inactive_collator(RuntimeOrigin::signed(COLLATOR_3), COLLATOR_1),
230
1
            Error::<Test>::CollatorNotOnline
231
1
        );
232
1
    });
233
1
}
234

            
235
#[test]
236
1
fn notify_inactive_collator_fails_if_collator_is_invulnerable() {
237
1
    ExtBuilder.build().execute_with(|| {
238
1
        make_collator_inactive(COLLATOR_2);
239
1
        assert_ok!(Pallet::<Test>::enable_offline_marking(
240
1
            RuntimeOrigin::root(),
241
1
            true
242
1
        ));
243
1
        assert_noop!(
244
1
            Pallet::<Test>::notify_inactive_collator(RuntimeOrigin::signed(COLLATOR_3), COLLATOR_2),
245
1
            Error::<Test>::MarkingInvulnerableOfflineInvalid
246
1
        );
247
1
    });
248
1
}