@@ -68,7 +68,7 @@ use futures::{
6868use std:: {
6969 collections:: {
7070 hash_map:: { Entry , HashMap } ,
71- BTreeSet , HashSet ,
71+ HashSet ,
7272 } ,
7373 time:: { Duration , Instant } ,
7474} ;
@@ -156,6 +156,7 @@ struct PerRelayParentState {
156156 seconding_limit : usize ,
157157 session : SessionIndex ,
158158 groups_per_para : HashMap < ParaId , Vec < GroupIndex > > ,
159+ disabled_validators : HashSet < ValidatorIndex > ,
159160}
160161
161162impl PerRelayParentState {
@@ -166,6 +167,17 @@ impl PerRelayParentState {
166167 fn active_validator_state_mut ( & mut self ) -> Option < & mut ActiveValidatorState > {
167168 self . local_validator . as_mut ( ) . and_then ( |local| local. active . as_mut ( ) )
168169 }
170+
171+ /// Returns `true` if the given validator is disabled in the context of the relay parent.
172+ pub fn is_disabled ( & self , validator_index : & ValidatorIndex ) -> bool {
173+ self . disabled_validators . contains ( validator_index)
174+ }
175+
176+ /// A convenience function to generate a disabled bitmask for the given backing group.
177+ /// The output bits are set to `true` for validators that are disabled.
178+ pub fn disabled_bitmask ( & self , group : & [ ValidatorIndex ] ) -> BitVec < u8 , Lsb0 > {
179+ BitVec :: from_iter ( group. iter ( ) . map ( |v| self . is_disabled ( v) ) )
180+ }
169181}
170182
171183// per-relay-parent local validator state.
@@ -206,8 +218,6 @@ struct PerSessionState {
206218 // getting the topology from the gossip-support subsystem
207219 grid_view : Option < grid:: SessionTopologyView > ,
208220 local_validator : Option < LocalValidatorIndex > ,
209- // We store the latest state here based on union of leaves.
210- disabled_validators : BTreeSet < ValidatorIndex > ,
211221}
212222
213223impl PerSessionState {
@@ -224,16 +234,7 @@ impl PerSessionState {
224234 )
225235 . map ( |( _, index) | LocalValidatorIndex :: Active ( index) ) ;
226236
227- let disabled_validators = BTreeSet :: new ( ) ;
228-
229- PerSessionState {
230- session_info,
231- groups,
232- authority_lookup,
233- grid_view : None ,
234- local_validator,
235- disabled_validators,
236- }
237+ PerSessionState { session_info, groups, authority_lookup, grid_view : None , local_validator }
237238 }
238239
239240 fn supply_topology (
@@ -269,33 +270,6 @@ impl PerSessionState {
269270 fn is_not_validator ( & self ) -> bool {
270271 self . grid_view . is_some ( ) && self . local_validator . is_none ( )
271272 }
272-
273- /// A convenience function to generate a disabled bitmask for the given backing group.
274- /// The output bits are set to `true` for validators that are disabled.
275- /// Returns `None` if the group index is out of bounds.
276- pub fn disabled_bitmask ( & self , group : GroupIndex ) -> Option < BitVec < u8 , Lsb0 > > {
277- let group = self . groups . get ( group) ?;
278- let mask = BitVec :: from_iter ( group. iter ( ) . map ( |v| self . is_disabled ( v) ) ) ;
279- Some ( mask)
280- }
281-
282- /// Returns `true` if the given validator is disabled in the current session.
283- pub fn is_disabled ( & self , validator_index : & ValidatorIndex ) -> bool {
284- self . disabled_validators . contains ( validator_index)
285- }
286-
287- /// Extend the list of disabled validators.
288- pub fn extend_disabled_validators (
289- & mut self ,
290- disabled : impl IntoIterator < Item = ValidatorIndex > ,
291- ) {
292- self . disabled_validators . extend ( disabled) ;
293- }
294-
295- /// Clear the list of disabled validators.
296- pub fn clear_disabled_validators ( & mut self ) {
297- self . disabled_validators . clear ( ) ;
298- }
299273}
300274
301275pub ( crate ) struct State {
@@ -582,19 +556,16 @@ pub(crate) async fn handle_active_leaves_update<Context>(
582556 let new_relay_parents =
583557 state. implicit_view . all_allowed_relay_parents ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
584558
585- // We clear the list of disabled validators to reset it properly based on union of leaves.
586- let mut cleared_disabled_validators: BTreeSet < SessionIndex > = BTreeSet :: new ( ) ;
587-
588559 for new_relay_parent in new_relay_parents. iter ( ) . cloned ( ) {
589- // Even if we processed this relay parent before, we need to fetch the list of disabled
590- // validators based on union of active leaves.
591- let disabled_validators =
560+ let disabled_validators: HashSet < _ > =
592561 polkadot_node_subsystem_util:: vstaging:: get_disabled_validators_with_fallback (
593562 ctx. sender ( ) ,
594563 new_relay_parent,
595564 )
596565 . await
597- . map_err ( JfyiError :: FetchDisabledValidators ) ?;
566+ . map_err ( JfyiError :: FetchDisabledValidators ) ?
567+ . into_iter ( )
568+ . collect ( ) ;
598569
599570 let session_index = polkadot_node_subsystem_util:: request_session_index_for_child (
600571 new_relay_parent,
@@ -644,10 +615,6 @@ pub(crate) async fn handle_active_leaves_update<Context>(
644615 . get_mut ( & session_index)
645616 . expect ( "either existed or just inserted; qed" ) ;
646617
647- if cleared_disabled_validators. insert ( session_index) {
648- per_session. clear_disabled_validators ( ) ;
649- }
650-
651618 if !disabled_validators. is_empty ( ) {
652619 gum:: debug!(
653620 target: LOG_TARGET ,
@@ -656,8 +623,6 @@ pub(crate) async fn handle_active_leaves_update<Context>(
656623 ?disabled_validators,
657624 "Disabled validators detected"
658625 ) ;
659-
660- per_session. extend_disabled_validators ( disabled_validators) ;
661626 }
662627
663628 if state. per_relay_parent . contains_key ( & new_relay_parent) {
@@ -723,6 +688,7 @@ pub(crate) async fn handle_active_leaves_update<Context>(
723688 seconding_limit,
724689 session : session_index,
725690 groups_per_para,
691+ disabled_validators,
726692 } ,
727693 ) ;
728694 }
@@ -1581,6 +1547,17 @@ async fn handle_incoming_statement<Context>(
15811547 } ;
15821548 let session_info = & per_session. session_info ;
15831549
1550+ if per_relay_parent. is_disabled ( & statement. unchecked_validator_index ( ) ) {
1551+ gum:: debug!(
1552+ target: LOG_TARGET ,
1553+ ?relay_parent,
1554+ validator_index = ?statement. unchecked_validator_index( ) ,
1555+ "Ignoring a statement from disabled validator."
1556+ ) ;
1557+ modify_reputation ( reputation, ctx. sender ( ) , peer, COST_DISABLED_VALIDATOR ) . await ;
1558+ return
1559+ }
1560+
15841561 let local_validator = match per_relay_parent. local_validator . as_mut ( ) {
15851562 None => {
15861563 // we shouldn't be receiving statements unless we're a validator
@@ -1614,17 +1591,6 @@ async fn handle_incoming_statement<Context>(
16141591 } ,
16151592 } ;
16161593
1617- if per_session. is_disabled ( & statement. unchecked_validator_index ( ) ) {
1618- gum:: debug!(
1619- target: LOG_TARGET ,
1620- ?relay_parent,
1621- validator_index = ?statement. unchecked_validator_index( ) ,
1622- "Ignoring a statement from disabled validator."
1623- ) ;
1624- modify_reputation ( reputation, ctx. sender ( ) , peer, COST_DISABLED_VALIDATOR ) . await ;
1625- return
1626- }
1627-
16281594 let ( active, cluster_sender_index) = {
16291595 // This block of code only returns `Some` when both the originator and
16301596 // the sending peer are in the cluster.
@@ -2376,21 +2342,18 @@ async fn handle_incoming_manifest_common<'a, Context>(
23762342 Some ( s) => s,
23772343 } ;
23782344
2379- let local_validator = match relay_parent_state. local_validator . as_mut ( ) {
2380- None => {
2381- if per_session. is_not_validator ( ) {
2382- modify_reputation (
2383- reputation,
2384- ctx. sender ( ) ,
2385- peer,
2386- COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE ,
2387- )
2388- . await ;
2389- }
2390- return None
2391- } ,
2392- Some ( x) => x,
2393- } ;
2345+ if relay_parent_state. local_validator . is_none ( ) {
2346+ if per_session. is_not_validator ( ) {
2347+ modify_reputation (
2348+ reputation,
2349+ ctx. sender ( ) ,
2350+ peer,
2351+ COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE ,
2352+ )
2353+ . await ;
2354+ }
2355+ return None
2356+ }
23942357
23952358 let Some ( expected_groups) = relay_parent_state. groups_per_para . get ( & para_id) else {
23962359 modify_reputation ( reputation, ctx. sender ( ) , peer, COST_MALFORMED_MANIFEST ) . await ;
@@ -2433,10 +2396,13 @@ async fn handle_incoming_manifest_common<'a, Context>(
24332396 let claimed_parent_hash = manifest_summary. claimed_parent_hash ;
24342397
24352398 // Ignore votes from disabled validators when counting towards the threshold.
2436- let disabled_mask = per_session. disabled_bitmask ( group_index) . unwrap_or_default ( ) ;
2399+ let group = per_session. groups . get ( group_index) . unwrap_or ( & [ ] ) ;
2400+ let disabled_mask = relay_parent_state. disabled_bitmask ( group) ;
24372401 manifest_summary. statement_knowledge . mask_seconded ( & disabled_mask) ;
24382402 manifest_summary. statement_knowledge . mask_valid ( & disabled_mask) ;
24392403
2404+ let local_validator = relay_parent_state. local_validator . as_mut ( ) . expect ( "checked above; qed" ) ;
2405+
24402406 let acknowledge = match local_validator. grid_tracker . import_manifest (
24412407 grid_topology,
24422408 & per_session. groups ,
@@ -3014,9 +2980,7 @@ pub(crate) async fn dispatch_requests<Context>(ctx: &mut Context, state: &mut St
30142980 }
30152981
30162982 // Add disabled validators to the unwanted mask.
3017- let disabled_mask = per_session
3018- . disabled_bitmask ( group_index)
3019- . expect ( "group existence checked above; qed" ) ;
2983+ let disabled_mask = relay_parent_state. disabled_bitmask ( group) ;
30202984 unwanted_mask. seconded_in_group |= & disabled_mask;
30212985 unwanted_mask. validated_in_group |= & disabled_mask;
30222986
@@ -3107,9 +3071,7 @@ pub(crate) async fn handle_response<Context>(
31073071 Some ( g) => g,
31083072 } ;
31093073
3110- let disabled_mask = per_session
3111- . disabled_bitmask ( group_index)
3112- . expect ( "group_index checked above; qed" ) ;
3074+ let disabled_mask = relay_parent_state. disabled_bitmask ( group) ;
31133075
31143076 let res = response. validate_response (
31153077 & mut state. request_manager ,
@@ -3254,7 +3216,7 @@ pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) {
32543216 Some ( s) => s,
32553217 } ;
32563218
3257- let local_validator = match relay_parent_state. local_validator . as_mut ( ) {
3219+ let local_validator = match relay_parent_state. local_validator . as_ref ( ) {
32583220 None => return ,
32593221 Some ( s) => s,
32603222 } ;
@@ -3333,12 +3295,16 @@ pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) {
33333295 validated_in_group : !mask. validated_in_group . clone ( ) ,
33343296 } ;
33353297
3336- // Ignore disabled validators from the latest state when sending the response.
3337- let disabled_mask =
3338- per_session. disabled_bitmask ( group_index) . expect ( "group existence checked; qed" ) ;
3298+ // Ignore disabled validators when sending the response.
3299+ let disabled_mask = relay_parent_state. disabled_bitmask ( group) ;
33393300 and_mask. mask_seconded ( & disabled_mask) ;
33403301 and_mask. mask_valid ( & disabled_mask) ;
33413302
3303+ let local_validator = match relay_parent_state. local_validator . as_mut ( ) {
3304+ None => return ,
3305+ Some ( s) => s,
3306+ } ;
3307+
33423308 let mut sent_filter = StatementFilter :: blank ( group_size) ;
33433309 let statements: Vec < _ > = relay_parent_state
33443310 . statement_store
0 commit comments