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
#![cfg(test)]
17
use {
18
    crate::tests::common::*,
19
    frame_support::{traits::Get, BoundedBTreeSet},
20
    pallet_inactivity_tracking::pallet::{ActiveCollatorsForCurrentSession, InactiveCollators},
21
    parity_scale_codec::Encode,
22
    sp_consensus_aura::AURA_ENGINE_ID,
23
    sp_runtime::{traits::BlakeTwo256, DigestItem},
24
    test_relay_sproof_builder::{HeaderAs, ParaHeaderSproofBuilder, ParaHeaderSproofBuilderItem},
25
    tp_traits::{NodeActivityTrackingHelper, ParaId},
26
};
27

            
28
1
fn note_blocks_for_container_chain(
29
1
    para_id_1: ParaId,
30
1
    para_id_2: ParaId,
31
1
    start_block: u32,
32
1
    end_block: u32,
33
1
) {
34
1
    // Simulate the inclusion of a block for a container chain
35
1
    let mut sproof = ParaHeaderSproofBuilder::default();
36

            
37
11
    for block_number in start_block..=end_block {
38
11
        let s1 = ParaHeaderSproofBuilderItem {
39
11
            para_id: para_id_1,
40
11
            author_id: HeaderAs::NonEncoded(sp_runtime::generic::Header::<u32, BlakeTwo256> {
41
11
                parent_hash: Default::default(),
42
11
                number: block_number,
43
11
                state_root: Default::default(),
44
11
                extrinsics_root: Default::default(),
45
11
                digest: sp_runtime::generic::Digest {
46
11
                    logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, 2u64.encode())],
47
11
                },
48
11
            }),
49
11
        };
50
11
        let s2 = ParaHeaderSproofBuilderItem {
51
11
            para_id: para_id_2,
52
11
            author_id: HeaderAs::NonEncoded(sp_runtime::generic::Header::<u32, BlakeTwo256> {
53
11
                parent_hash: Default::default(),
54
11
                number: block_number,
55
11
                state_root: Default::default(),
56
11
                extrinsics_root: Default::default(),
57
11
                digest: sp_runtime::generic::Digest {
58
11
                    logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, 3u64.encode())],
59
11
                },
60
11
            }),
61
11
        };
62
11
        sproof.items.push(s1);
63
11
        sproof.items.push(s2);
64
11
    }
65
1
    set_author_noting_inherent_data(sproof.clone())
66
1
}
67

            
68
6
fn get_collators_set(
69
6
    collators: Vec<cumulus_primitives_core::relay_chain::AccountId>,
70
6
) -> BoundedBTreeSet<
71
6
    cumulus_primitives_core::relay_chain::AccountId,
72
6
    <Runtime as pallet_inactivity_tracking::Config>::MaxCollatorsPerSession,
73
6
> {
74
6
    let mut collator_set: BoundedBTreeSet<
75
6
        cumulus_primitives_core::relay_chain::AccountId,
76
6
        <Runtime as pallet_inactivity_tracking::Config>::MaxCollatorsPerSession,
77
6
    > = BoundedBTreeSet::new();
78
10
    collators.iter().for_each(|collator| {
79
10
        collator_set.try_insert(collator.clone()).ok();
80
10
    });
81
6
    collator_set
82
6
}
83

            
84
#[test]
85
1
fn inactivity_tracking_correctly_updates_storages() {
86
1
    ExtBuilder::default()
87
1
        .with_empty_parachains(vec![3000, 3001])
88
1
        .with_collators(vec![
89
1
            (AccountId::from(ALICE), 100_000),
90
1
            (AccountId::from(BOB), 100_000),
91
1
            (AccountId::from(CHARLIE), 100_000),
92
1
            (AccountId::from(DAVE), 100_000),
93
1
        ])
94
1
        .build()
95
1
        .execute_with(|| {
96
1
            let assignment = TanssiCollatorAssignment::collator_container_chain();
97
1
            assert_eq!(
98
1
                assignment.container_chains[&3000.into()],
99
1
                vec![ALICE.into(), BOB.into()]
100
1
            );
101
1
            assert_eq!(
102
1
                assignment.container_chains[&3001.into()],
103
1
                vec![CHARLIE.into(), DAVE.into()]
104
1
            );
105
1
            note_blocks_for_container_chain(3000.into(), 3001.into(), 1, session_to_block(1));
106
1
            run_block();
107
1
            assert_eq!(
108
1
                <ActiveCollatorsForCurrentSession<Runtime>>::get(),
109
1
                get_collators_set(vec![ALICE.into(), DAVE.into()])
110
1
            );
111

            
112
1
            run_block();
113
1
            assert_eq!(
114
1
                <ActiveCollatorsForCurrentSession<Runtime>>::get(),
115
1
                get_collators_set(vec![ALICE.into(), DAVE.into()])
116
1
            );
117

            
118
1
            run_to_session(1);
119
1
            run_block();
120
1
            assert_eq!(
121
1
                <InactiveCollators<Runtime>>::get(0),
122
1
                get_collators_set(vec![BOB.into(), CHARLIE.into()])
123
1
            );
124
1
            assert_eq!(
125
1
                <ActiveCollatorsForCurrentSession<Runtime>>::get(),
126
1
                get_collators_set(vec![])
127
1
            );
128

            
129
1
            run_block();
130
1
            assert_eq!(
131
1
                <ActiveCollatorsForCurrentSession<Runtime>>::get(),
132
1
                get_collators_set(vec![])
133
1
            );
134
1
            run_to_session(2);
135
1
            run_block();
136
1
            assert_eq!(
137
1
                <InactiveCollators<Runtime>>::get(1),
138
1
                get_collators_set(vec![ALICE.into(), BOB.into(), CHARLIE.into(), DAVE.into()])
139
1
            );
140
1
            assert_eq!(<ActiveCollatorsForCurrentSession<Runtime>>::get().len(), 0);
141

            
142
1
            let max_inactive_sessions =
143
1
                <Runtime as pallet_inactivity_tracking::Config>::MaxInactiveSessions::get();
144
1
            run_to_session(max_inactive_sessions - 1);
145
1
            run_block();
146
1
            assert_eq!(
147
1
                InactivityTracking::is_node_inactive(&AccountId::from(ALICE)),
148
1
                false
149
1
            );
150
1
            assert_eq!(
151
1
                InactivityTracking::is_node_inactive(&AccountId::from(BOB)),
152
1
                false
153
1
            );
154
1
            assert_eq!(
155
1
                InactivityTracking::is_node_inactive(&AccountId::from(CHARLIE)),
156
1
                false
157
1
            );
158
1
            assert_eq!(
159
1
                InactivityTracking::is_node_inactive(&AccountId::from(DAVE)),
160
1
                false
161
1
            );
162

            
163
1
            run_to_session(max_inactive_sessions);
164
1
            assert_eq!(
165
1
                InactivityTracking::is_node_inactive(&AccountId::from(ALICE)),
166
1
                false
167
1
            );
168
1
            assert_eq!(
169
1
                InactivityTracking::is_node_inactive(&AccountId::from(BOB)),
170
1
                true
171
1
            );
172
1
            assert_eq!(
173
1
                InactivityTracking::is_node_inactive(&AccountId::from(CHARLIE)),
174
1
                true
175
1
            );
176
1
            assert_eq!(
177
1
                InactivityTracking::is_node_inactive(&AccountId::from(DAVE)),
178
1
                false
179
1
            );
180
1
            assert_eq!(<InactiveCollators<Runtime>>::get(0).is_empty(), false);
181

            
182
1
            run_to_session(max_inactive_sessions + 1);
183
1
            run_block();
184
1

            
185
1
            assert_eq!(<InactiveCollators<Runtime>>::get(0).is_empty(), true);
186
1
        });
187
1
}