@@ -32,19 +32,35 @@ where
32
32
/// Updates the session index of [`pallet_session`].
33
33
// Instead of Some((*).expect) we could just use (*). However, we rather panic in presence of important programming errors.
34
34
fn new_session ( new_index : SessionIndex ) -> Option < Vec < T :: AccountId > > {
35
- info ! ( "Session manager: new_session {new_index}" ) ;
35
+ info ! ( "💼 Session manager: new_session {new_index}" ) ;
36
36
let new_committee = crate :: Pallet :: < T > :: rotate_committee_to_next_epoch ( ) . expect (
37
37
"Session should never end without current epoch validators defined. \
38
38
Check ShouldEndSession implementation or if it is used before starting new session",
39
39
) ;
40
40
41
- provide_committee_accounts :: < T > ( & new_committee ) ;
42
- register_committee_keys :: < T > ( & new_committee ) ;
41
+ let old_committee_accounts = crate :: ProvidedAccounts :: < T > :: take ( ) ;
42
+ let mut new_committee_accounts : BTreeSet < T :: AccountId > = BTreeSet :: new ( ) ;
43
43
44
- let new_committee_accounts =
45
- new_committee . into_iter ( ) . map ( |member| member. authority_id ( ) . into ( ) ) . collect ( ) ;
44
+ for member in new_committee . iter ( ) {
45
+ let account = member. authority_id ( ) . into ( ) ;
46
46
47
- Some ( new_committee_accounts)
47
+ if !new_committee_accounts. contains ( & account) {
48
+ new_committee_accounts. insert ( account. clone ( ) ) ;
49
+
50
+ // Members that were already in the old committee have their accounts and keys set up already
51
+ if !old_committee_accounts. contains ( & account) {
52
+ setup_block_producer :: < T > ( account, member. authority_keys ( ) ) ;
53
+ }
54
+ }
55
+ }
56
+
57
+ for account in old_committee_accounts. difference ( & new_committee_accounts) {
58
+ teardown_block_producer :: < T > ( account)
59
+ }
60
+
61
+ crate :: ProvidedAccounts :: < T > :: set ( new_committee_accounts. clone ( ) . try_into ( ) . unwrap ( ) ) ;
62
+
63
+ Some ( new_committee. into_iter ( ) . map ( |member| member. authority_id ( ) . into ( ) ) . collect ( ) )
48
64
}
49
65
50
66
fn end_session ( end_index : SessionIndex ) {
@@ -58,51 +74,47 @@ where
58
74
}
59
75
}
60
76
61
- // Registers keys of new committee members in the session pallet. This is necessary, as the pallet
62
- // requires the keys to be registered prior to session start and we do not wish to force block
63
- // producers to do it manually.
64
- fn register_committee_keys < T : crate :: Config + pallet_session:: Config > (
65
- new_committee : & [ T :: CommitteeMember ] ,
77
+ /// Provides accounts and registers keys for new committee members
78
+ fn setup_block_producer < T : crate :: Config + pallet_session:: Config > (
79
+ account : T :: AccountId ,
80
+ keys : T :: AuthorityKeys ,
66
81
) where
67
82
<T as pallet_session:: Config >:: Keys : From < T :: AuthorityKeys > ,
68
83
{
69
- let mut keys_added : BTreeSet < T :: AccountId > = BTreeSet :: new ( ) ;
70
- for member in new_committee . iter ( ) {
71
- let account_id = member . authority_id ( ) . into ( ) ;
84
+ log :: debug! (
85
+ "➕💼 Incrementing provider count and registering keys for block producer {account:?}"
86
+ ) ;
72
87
73
- if keys_added. contains ( & account_id) {
74
- continue ;
75
- }
88
+ frame_system:: Pallet :: < T > :: inc_providers ( & account) ;
76
89
77
- keys_added. insert ( account_id. clone ( ) ) ;
78
- let call = pallet_session:: Call :: < T > :: set_keys {
79
- keys : From :: from ( member. authority_keys ( ) ) ,
80
- proof : vec ! [ ] ,
81
- } ;
82
- let call_result = call. dispatch_bypass_filter ( RawOrigin :: Signed ( account_id. clone ( ) ) . into ( ) ) ;
83
- match call_result {
84
- Ok ( _) => debug ! ( "set_keys for {account_id:?}" ) ,
85
- Err ( e) => info ! ( "Could not set_keys for {account_id:?}, error: {:?}" , e. error) ,
86
- }
90
+ let set_keys_result = pallet_session:: Call :: < T > :: set_keys { keys : keys. into ( ) , proof : vec ! [ ] }
91
+ . dispatch_bypass_filter ( RawOrigin :: Signed ( account. clone ( ) ) . into ( ) ) ;
92
+
93
+ match set_keys_result {
94
+ Ok ( _) => debug ! ( "set_keys for {account:?}" ) ,
95
+ Err ( e) => {
96
+ info ! ( "Could not set_keys for {account:?}, error: {:?}" , e. error)
97
+ } ,
87
98
}
88
99
}
89
100
90
- // Ensures that all accounts tied to new committee members exist by incrementing their
91
- // account provider counts. This is a necessary temporary solution, because we don't check
92
- // whether a block producer's account exists or not, when selecting them to a committee.
93
- // A proper solution would either be:
94
- // - increasing provider count for an account for as long as it is in the active committee
95
- // and decreasing it afterwards, or
96
- // - considering account existence when selecting the committee
97
- // This will be addressed in later development.
98
- pub ( crate ) fn provide_committee_accounts < T : crate :: Config > ( new_committee : & [ T :: CommitteeMember ] ) {
99
- let new_accs: BTreeSet < T :: AccountId > =
100
- new_committee. iter ( ) . map ( |m| m. authority_id ( ) . into ( ) ) . collect ( ) ;
101
- for account in new_accs {
102
- if !frame_system:: Pallet :: < T > :: account_exists ( & account) {
103
- frame_system:: Pallet :: < T > :: inc_providers ( & account) ;
104
- }
101
+ /// Removes account provisions and purges keys for outgoing old committee members
102
+ fn teardown_block_producer < T : crate :: Config + pallet_session:: Config > ( account : & T :: AccountId )
103
+ where
104
+ <T as pallet_session:: Config >:: Keys : From < T :: AuthorityKeys > ,
105
+ {
106
+ let purge_keys_result = pallet_session:: Call :: < T > :: purge_keys { }
107
+ . dispatch_bypass_filter ( RawOrigin :: Signed ( account. clone ( ) ) . into ( ) ) ;
108
+ match purge_keys_result {
109
+ Ok ( _) => debug ! ( "purge_keys for {account:?}" ) ,
110
+ Err ( e) => info ! ( "Could not purge_keys for {account:?}, error: {:?}" , e. error) ,
105
111
}
112
+ log:: info!(
113
+ "➖💼 Decrementing provider count and deregisteringkeys for block producer {account:?}"
114
+ ) ;
115
+ frame_system:: Pallet :: < T > :: dec_providers ( & account) . expect (
116
+ "We always match dec_providers with corresponding inc_providers, thus it cannot fail" ,
117
+ ) ;
106
118
}
107
119
108
120
/// Tries to end each session in the first block of each partner chains epoch in which the committee for the epoch is defined.
@@ -126,7 +138,7 @@ where
126
138
false
127
139
}
128
140
} else {
129
- debug ! ( "PalletSessionSupport : should_end_session({n:?}) = false" ) ;
141
+ debug ! ( "Session manager : should_end_session({n:?}) = false" ) ;
130
142
false
131
143
}
132
144
}
0 commit comments