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
extern crate alloc;
21

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

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

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

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

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

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

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

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

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

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

            
92
1322
                return;
93
3434
            }
94
3434

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

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

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