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
//! # Nimbus Collator Assignment Pallet
18

            
19
#![cfg_attr(not(feature = "std"), no_std)]
20

            
21
pub use pallet::*;
22
use {
23
    dp_collator_assignment::AssignedCollators,
24
    frame_support::pallet_prelude::*,
25
    sp_runtime::{
26
        traits::{AtLeast32BitUnsigned, One, Zero},
27
        Saturating,
28
    },
29
    sp_std::{collections::btree_map::BTreeMap, prelude::*, vec},
30
};
31

            
32
#[cfg(test)]
33
mod mock;
34

            
35
#[cfg(test)]
36
mod tests;
37

            
38
3708
#[frame_support::pallet]
39
pub mod pallet {
40
    use super::*;
41

            
42
68755
    #[pallet::pallet]
43
    pub struct Pallet<T>(_);
44

            
45
    /// Configure the pallet by specifying the parameters and types on which it depends.
46
    #[pallet::config]
47
    pub trait Config: frame_system::Config {
48
        type SessionIndex: parity_scale_codec::FullCodec
49
            + TypeInfo
50
            + Copy
51
            + AtLeast32BitUnsigned
52
            + MaxEncodedLen;
53
        type AuthorityId: parity_scale_codec::FullCodec + TypeInfo + Clone;
54
    }
55

            
56
66663
    #[pallet::storage]
57
    #[pallet::unbounded]
58
    pub type CollatorContainerChain<T: Config> = StorageMap<
59
        _,
60
        Twox64Concat,
61
        T::SessionIndex,
62
        AssignedCollators<T::AuthorityId>,
63
        OptionQuery,
64
    >;
65

            
66
618
    #[pallet::call]
67
    impl<T: Config> Pallet<T> {}
68

            
69
    impl<T: Config> Pallet<T> {
70
        /// Assign new collators
71
        /// collators should be queued collators
72
4692
        pub fn assign_collators(
73
4692
            current_session_index: &T::SessionIndex,
74
4692
            queued_id_to_nimbus_map: &BTreeMap<T::AccountId, T::AuthorityId>,
75
4692
            next_collator_assignment: &AssignedCollators<T::AccountId>,
76
4692
        ) {
77
4692
            let next_nimbus_assignment = next_collator_assignment
78
10359
                .map(|account_id| queued_id_to_nimbus_map[account_id].clone());
79
4692

            
80
4692
            // Only applies to session index 0
81
4692
            if current_session_index == &T::SessionIndex::zero() {
82
1306
                CollatorContainerChain::<T>::insert(
83
1306
                    current_session_index,
84
1306
                    next_nimbus_assignment.clone(),
85
1306
                );
86
1306
                CollatorContainerChain::<T>::insert(
87
1306
                    current_session_index.saturating_add(T::SessionIndex::one()),
88
1306
                    next_nimbus_assignment,
89
1306
                );
90
1306

            
91
1306
                return;
92
3386
            }
93
3386

            
94
3386
            // Remove value at session - 1, insert new value at session + 1
95
3386
            CollatorContainerChain::<T>::remove(
96
3386
                current_session_index.saturating_sub(T::SessionIndex::one()),
97
3386
            );
98
3386
            CollatorContainerChain::<T>::insert(
99
3386
                current_session_index.saturating_add(T::SessionIndex::one()),
100
3386
                next_nimbus_assignment,
101
3386
            );
102
4692
        }
103

            
104
4692
        pub fn initializer_on_new_session(
105
4692
            current_session_index: &T::SessionIndex,
106
4692
            queued_id_to_nimbus_map: &BTreeMap<T::AccountId, T::AuthorityId>,
107
4692
            next_collator_assignment: &AssignedCollators<T::AccountId>,
108
4692
        ) {
109
4692
            Self::assign_collators(
110
4692
                current_session_index,
111
4692
                queued_id_to_nimbus_map,
112
4692
                next_collator_assignment,
113
4692
            )
114
4692
        }
115

            
116
56630
        pub fn collator_container_chain(
117
56630
            session_index: T::SessionIndex,
118
56630
        ) -> Option<AssignedCollators<T::AuthorityId>> {
119
56630
            CollatorContainerChain::<T>::get(session_index)
120
56630
        }
121
    }
122
}