@@ -49,20 +49,29 @@ where
4949 let mut new_committee_accounts: BTreeSet < T :: AccountId > = BTreeSet :: new ( ) ;
5050
5151 for member in new_committee. iter ( ) {
52- let account = member. authority_id ( ) . into ( ) ;
52+ let account: T :: AccountId = member. authority_id ( ) . into ( ) ;
5353
5454 if !new_committee_accounts. contains ( & account) {
5555 new_committee_accounts. insert ( account. clone ( ) ) ;
5656
57- // Members that were already in the old committee have their accounts and keys set up already
57+ // Members that were already in the old committee have their accounts provided
5858 if !old_committee_accounts. contains ( & account) {
59- setup_block_producer :: < T > ( account, member. authority_keys ( ) ) ;
59+ provide_account :: < T > ( & account) ;
60+ }
61+
62+ let new_keys = member. authority_keys ( ) ;
63+ let current_keys = load_keys :: < T > ( & account) ;
64+
65+ if current_keys != Some ( new_keys. clone ( ) . into ( ) ) {
66+ purge_keys :: < T > ( & account) ;
67+ set_keys :: < T > ( & account, new_keys. clone ( ) ) ;
6068 }
6169 }
6270 }
6371
6472 for account in old_committee_accounts. difference ( & new_committee_accounts) {
65- teardown_block_producer :: < T > ( account)
73+ purge_keys :: < T > ( account) ;
74+ unprovide_account :: < T > ( account) ;
6675 }
6776
6877 crate :: ProvidedAccounts :: < T > :: set ( new_committee_accounts. clone ( ) . try_into ( ) . unwrap ( ) ) ;
@@ -81,19 +90,19 @@ where
8190 }
8291}
8392
84- /// Provides accounts and registers keys for new committee members
85- fn setup_block_producer < T : crate :: Config + pallet_session:: Config > (
86- account : T :: AccountId ,
93+ fn load_keys < T : pallet_session:: Config > ( account : & T :: AccountId ) -> Option < T :: Keys > {
94+ <T as pallet_session:: Config >:: ValidatorId :: try_from ( account. clone ( ) )
95+ . ok ( )
96+ . as_ref ( )
97+ . and_then ( pallet_session:: Pallet :: < T > :: load_keys)
98+ }
99+
100+ fn set_keys < T : crate :: Config + pallet_session:: Config > (
101+ account : & T :: AccountId ,
87102 keys : T :: AuthorityKeys ,
88103) where
89104 <T as pallet_session:: Config >:: Keys : From < T :: AuthorityKeys > ,
90105{
91- log:: debug!(
92- "➕💼 Incrementing provider count and registering keys for block producer {account:?}"
93- ) ;
94-
95- frame_system:: Pallet :: < T > :: inc_providers ( & account) ;
96-
97106 let set_keys_result = pallet_session:: Call :: < T > :: set_keys { keys : keys. into ( ) , proof : vec ! [ ] }
98107 . dispatch_bypass_filter ( RawOrigin :: Signed ( account. clone ( ) ) . into ( ) ) ;
99108
@@ -105,8 +114,7 @@ fn setup_block_producer<T: crate::Config + pallet_session::Config>(
105114 }
106115}
107116
108- /// Removes account provisions and purges keys for outgoing old committee members
109- fn teardown_block_producer < T : crate :: Config + pallet_session:: Config > ( account : & T :: AccountId )
117+ fn purge_keys < T : crate :: Config + pallet_session:: Config > ( account : & T :: AccountId )
110118where
111119 <T as pallet_session:: Config >:: Keys : From < T :: AuthorityKeys > ,
112120{
@@ -116,8 +124,19 @@ where
116124 Ok ( _) => debug ! ( "purge_keys for {account:?}" ) ,
117125 Err ( e) => info ! ( "Could not purge_keys for {account:?}, error: {:?}" , e. error) ,
118126 }
127+ }
128+
129+ fn provide_account < T : crate :: Config + pallet_session:: Config > ( account : & T :: AccountId ) {
130+ log:: debug!(
131+ "➕💼 Incrementing provider count and registering keys for block producer {account:?}"
132+ ) ;
133+
134+ frame_system:: Pallet :: < T > :: inc_providers ( & account) ;
135+ }
136+
137+ fn unprovide_account < T : crate :: Config + pallet_session:: Config > ( account : & T :: AccountId ) {
119138 log:: info!(
120- "➖💼 Decrementing provider count and deregisteringkeys for block producer {account:?}"
139+ "➖💼 Decrementing provider count and deregistering keys for block producer {account:?}"
121140 ) ;
122141 frame_system:: Pallet :: < T > :: dec_providers ( & account) . expect (
123142 "We always match dec_providers with corresponding inc_providers, thus it cannot fail" ,
@@ -167,6 +186,7 @@ mod tests {
167186 use pallet_session:: ShouldEndSession ;
168187 pub const IRRELEVANT : u64 = 2 ;
169188 use sidechain_domain:: ScEpochNumber ;
189+ use sp_runtime:: testing:: UintAuthorityId ;
170190
171191 type Manager = crate :: Pallet < Test > ;
172192
@@ -209,6 +229,40 @@ mod tests {
209229 } ) ;
210230 }
211231
232+ #[ test]
233+ fn reregister_changed_session_keys_for_sitting_authority ( ) {
234+ new_test_ext ( ) . execute_with ( || {
235+ set_validators_directly ( & [ dave ( ) , eve ( ) ] , 1 ) . unwrap ( ) ;
236+ // By default, the session keys are not set for the account.
237+ assert_eq ! ( Session :: load_keys( & dave( ) . account_id( ) ) , None ) ;
238+ assert_eq ! ( Session :: load_keys( & eve( ) . account_id( ) ) , None ) ;
239+ increment_epoch ( ) ;
240+
241+ start_session ( 1 ) ;
242+
243+ // After setting the keys, they should be stored in the session.
244+ assert_eq ! ( Session :: load_keys( & dave( ) . account_id( ) ) , Some ( dave( ) . authority_keys) ) ;
245+ assert_eq ! ( Session :: load_keys( & eve( ) . account_id( ) ) , Some ( eve( ) . authority_keys) ) ;
246+
247+ let eve_with_different_keys = MockValidator {
248+ name : "Eve with different keys" ,
249+ authority_keys : SessionKeys { foo : UintAuthorityId ( 44 ) } ,
250+ ..eve ( )
251+ } ;
252+
253+ // Eve is re-elected to the committee, but is using different keys now
254+ set_validators_directly ( & [ dave ( ) , eve_with_different_keys. clone ( ) ] , 2 ) . unwrap ( ) ;
255+ increment_epoch ( ) ;
256+ start_session ( 2 ) ;
257+
258+ // Eve's keys were updated
259+ assert_eq ! (
260+ Session :: load_keys( & eve( ) . account_id( ) ) ,
261+ Some ( eve_with_different_keys. authority_keys)
262+ ) ;
263+ } ) ;
264+ }
265+
212266 #[ test]
213267 fn ends_two_sessions_and_rotates_once_when_committee_changes ( ) {
214268 new_test_ext ( ) . execute_with ( || {
0 commit comments