Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of the new validator disabling strategy #2226

Merged
merged 99 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
913232a
Handling of disabled validators in backing subsystem (#1259)
tdimitrov Oct 20, 2023
42607ad
Merge branch 'master' into tsv-disabling
tdimitrov Oct 24, 2023
5a6ad28
Merge branch 'master' into tsv-disabling
ordian Oct 26, 2023
c986fd3
Merge branch 'master' into tsv-disabling
tdimitrov Nov 6, 2023
b16c8b6
Merge branch 'master' into tsv-disabling
tdimitrov Nov 6, 2023
bbb6631
Any offender is disabled for a whole era - wip
tdimitrov Nov 8, 2023
c80ae21
Fix `on_offence` compilation errors
tdimitrov Nov 9, 2023
8f5d2b6
Remove `DisableStrategy`
tdimitrov Nov 9, 2023
c8adffe
Merge branch 'master' into tsv-disabling
tdimitrov Nov 9, 2023
2507584
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Nov 9, 2023
bff0240
Fix a compilation error after merge master: `CandidateValidationMessa…
tdimitrov Nov 9, 2023
e601dee
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Nov 9, 2023
95aa673
Update a comment
tdimitrov Nov 10, 2023
873e072
Update comments
tdimitrov Nov 14, 2023
02814e0
Merge branch 'master' into tsv-disabling
tdimitrov Nov 14, 2023
5afbfe3
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Nov 14, 2023
129a986
Replace `OffendingValidatorsThreshold` with `disabling_threshold`. Do…
tdimitrov Nov 13, 2023
ce1539c
Make tests pass
tdimitrov Nov 13, 2023
aee9fe3
Update tests to cover the new disabling strategy
tdimitrov Nov 15, 2023
d23c530
Storage migration for `OffendingValidators`
tdimitrov Nov 15, 2023
d2c5895
Apply suggestions from code review
tdimitrov Nov 16, 2023
06e79d9
Fix storage migration - use `VersionedMigration`, fix storage alias, …
tdimitrov Nov 16, 2023
9f8c598
Rename `disabling_threshold` -> `disabling_limit`
tdimitrov Nov 16, 2023
61b8c22
Merge branch 'master' into tsv-disabling
tdimitrov Nov 16, 2023
0a39a15
Fix test-staking-e2e
tdimitrov Nov 16, 2023
f4f82ec
Fix a compilation error
tdimitrov Nov 16, 2023
879279b
Fix compilation errors in benchmarks
tdimitrov Nov 16, 2023
3f4adaa
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Nov 21, 2023
5936d69
Extract `DisablingStrategy` as a trait
tdimitrov Nov 24, 2023
f330b61
Merge branch 'master' into tsv-disabling
tdimitrov Nov 29, 2023
5e8b367
Fix compilation errors after merge
tdimitrov Nov 29, 2023
f2d4c48
Filter votes from disabled validators in `BackedCandidates` in proces…
tdimitrov Nov 30, 2023
9cb65f8
Fix a typo
tdimitrov Dec 5, 2023
ed203d8
Do not chill validators on offence
tdimitrov Dec 7, 2023
a954ca5
Merge branch 'master' into tsv-disabling
tdimitrov Dec 7, 2023
a210f37
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Dec 7, 2023
6097a32
Don't disable for offences in previous eras
tdimitrov Dec 13, 2023
3109a29
Code review feedback - rework `enters_emergency_phase_after_forcing_b…
tdimitrov Dec 13, 2023
41ce978
Add `DisablingStrategy` to benchmarking mocks
tdimitrov Dec 14, 2023
28d5055
Fix a comment
tdimitrov Dec 14, 2023
71b6f60
`try_state` check for `DisabledValidators`
tdimitrov Dec 14, 2023
790cf4a
Fix another comment
tdimitrov Dec 14, 2023
6dfd0bc
Apply suggestions from code review
tdimitrov Dec 14, 2023
cd185b6
Fix a comment
tdimitrov Dec 14, 2023
cc09228
debug_assert for `DisabledValidators` being sorted
tdimitrov Dec 14, 2023
2552cb6
Unit tests for `UpToByzantineThresholdDisablingStrategy`
tdimitrov Dec 18, 2023
327b9fd
Remove struct DisablingDecision
tdimitrov Jan 2, 2024
c187d50
pub DisablingDecisionContext
tdimitrov Jan 2, 2024
e1899ce
Extract disabling threshold as a generic parameter of `UpToByzantineT…
tdimitrov Jan 4, 2024
1d283dc
Changelog and prdoc
tdimitrov Jan 4, 2024
1ef6e83
Fetch offender info and active set via staking pallet in `make_disabl…
tdimitrov Jan 5, 2024
55ccffe
UpToByzantineThresholdDisablingStrategy -> UpToThresholdDisablingStra…
tdimitrov Jan 5, 2024
52de0f5
Remove `set_validation_intention_after_chilled` from test-staking-e2e…
tdimitrov Jan 5, 2024
87af293
fmt
tdimitrov Jan 5, 2024
3506229
Merge branch 'master' into tsv-disabling
tdimitrov Jan 5, 2024
93f5189
Fix a compilation error from merge
tdimitrov Jan 5, 2024
2cf308f
Merge branch 'master' into tsv-disabling
tdimitrov Jan 8, 2024
68585e1
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Jan 8, 2024
21e662b
Merge branch 'master' into tsv-disabling
tdimitrov Jan 9, 2024
ceb6941
Apply suggestions from code review
tdimitrov Jan 15, 2024
8d56d2f
Return early in `make_disabling_decision` implementation for `UpToThr…
tdimitrov Jan 15, 2024
db43ae1
Remove stale TODO
tdimitrov Jan 15, 2024
18eae58
`DISABLING_FACTOR` becomes `SLASHING_DISABLING_FACTOR` in test-stakin…
tdimitrov Jan 15, 2024
cec4bbe
Don't divide by 0 in `disable_threshold` from `UpToThresholdDisabling…
tdimitrov Jan 15, 2024
859770a
Ensure only the expected set of validators is disabled in `mass_slash…
tdimitrov Jan 16, 2024
6f0d216
Merge branch 'tsv-disabling' into tsv-disabling-for-era
ordian Jan 16, 2024
48da767
Merge branch 'master' into tsv-disabling
tdimitrov Jan 16, 2024
e94fa2c
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Jan 16, 2024
3511b06
Use `defensive!` in disabling threshold calculation
tdimitrov Jan 16, 2024
9a775a5
`make_disabling_decision` returns an `Option` instead of a `Vec`
tdimitrov Jan 17, 2024
0111e69
Update substrate/frame/staking/CHANGELOG.md
tdimitrov Jan 17, 2024
9786407
Merge branch 'master' into tsv-disabling
tdimitrov Jan 18, 2024
5c3e98e
Merge branch 'tsv-disabling' into tsv-disabling-for-era
tdimitrov Jan 18, 2024
aed68dd
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Jan 29, 2024
755192b
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Feb 2, 2024
00456ae
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Feb 28, 2024
460ffd6
Fix a compilation error after merge
tdimitrov Feb 28, 2024
aaf8ee8
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Feb 28, 2024
3f4e73a
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Mar 1, 2024
80fabc5
Update substrate/frame/staking/src/migrations.rs
tdimitrov Mar 12, 2024
9aa8b70
Remove `disabled_validators` getter from `DisabledValidators`
tdimitrov Mar 12, 2024
4e0c3cf
Fix the migration - clear `OffendingValidators` by using `take` inste…
tdimitrov Mar 12, 2024
b71e0db
Ensure `OffendingValidators` after migrating to V15
tdimitrov Mar 12, 2024
37b7c4a
`make_disabling_decision` -> `decision`
tdimitrov Mar 12, 2024
fdb49a3
`DISABLING_THRESHOLD_FACTOR` -> `DISABLING_LIMIT_FACTOR`
tdimitrov Mar 12, 2024
301f48e
Update prdoc
tdimitrov Mar 12, 2024
e3a8528
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Mar 20, 2024
abe8e99
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Apr 11, 2024
cb11fb9
Fix migration
tdimitrov Apr 11, 2024
64ba884
Fix storage migration of `OffendingValidators` (#4083)
tdimitrov Apr 12, 2024
8a509f5
Code review feedback
tdimitrov Apr 23, 2024
049c545
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Apr 23, 2024
d4e4ab3
".git/.scripts/commands/fmt/fmt.sh"
Apr 23, 2024
f84162c
Fix `virtual_nominators_are_lazily_slashed`
tdimitrov Apr 23, 2024
87112ac
Fix `decision` from `UpToLimitDisablingStrategy` (#4262)
tdimitrov Apr 24, 2024
8db8167
Update substrate/frame/staking/src/slashing.rs
tdimitrov Apr 24, 2024
b76e5e7
Update substrate/frame/staking/src/pallet/impls.rs
tdimitrov Apr 24, 2024
a228aff
Remove misleading comment
tdimitrov Apr 25, 2024
1e90461
Merge branch 'master' into tsv-disabling-for-era
tdimitrov Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 73 additions & 14 deletions polkadot/node/core/backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ use statement_table::{
},
Config as TableConfig, Context as TableContextTrait, Table,
};
use util::vstaging::get_disabled_validators_with_fallback;

mod error;

Expand Down Expand Up @@ -383,6 +384,21 @@ struct TableContext {
validator: Option<Validator>,
groups: HashMap<ParaId, Vec<ValidatorIndex>>,
validators: Vec<ValidatorId>,
disabled_validators: Vec<ValidatorIndex>,
}

impl TableContext {
// Returns `true` if the provided `ValidatorIndex` is in the disabled validators list
pub fn validator_is_disabled(&self, validator_idx: &ValidatorIndex) -> bool {
self.disabled_validators
.iter()
.any(|disabled_val_idx| *disabled_val_idx == *validator_idx)
}

// Returns `true` if the local validator is in the disabled validators list
pub fn local_validator_is_disabled(&self) -> Option<bool> {
self.validator.as_ref().map(|v| v.disabled())
}
}

impl TableContextTrait for TableContext {
Expand Down Expand Up @@ -1010,21 +1026,33 @@ async fn construct_per_relay_parent_state<Context>(
let minimum_backing_votes =
try_runtime_api!(request_min_backing_votes(parent, session_index, ctx.sender()).await);

// TODO: https://github.com/paritytech/polkadot-sdk/issues/1940
// Once runtime ver `DISABLED_VALIDATORS_RUNTIME_REQUIREMENT` is released remove this call to
// `get_disabled_validators_with_fallback`, add `request_disabled_validators` call to the
// `try_join!` above and use `try_runtime_api!` to get `disabled_validators`
let disabled_validators = get_disabled_validators_with_fallback(ctx.sender(), parent)
.await
.map_err(Error::UtilError)?;

let signing_context = SigningContext { parent_hash: parent, session_index };
let validator =
match Validator::construct(&validators, signing_context.clone(), keystore.clone()) {
Ok(v) => Some(v),
Err(util::Error::NotAValidator) => None,
Err(e) => {
gum::warn!(
target: LOG_TARGET,
err = ?e,
"Cannot participate in candidate backing",
);
let validator = match Validator::construct(
&validators,
&disabled_validators,
signing_context.clone(),
keystore.clone(),
) {
Ok(v) => Some(v),
Err(util::Error::NotAValidator) => None,
Err(e) => {
gum::warn!(
target: LOG_TARGET,
err = ?e,
"Cannot participate in candidate backing",
);

return Ok(None)
},
};
return Ok(None)
},
};

let mut groups = HashMap::new();
let n_cores = cores.len();
Expand Down Expand Up @@ -1054,7 +1082,7 @@ async fn construct_per_relay_parent_state<Context>(
}
}

let table_context = TableContext { groups, validators, validator };
let table_context = TableContext { validator, groups, validators, disabled_validators };
let table_config = TableConfig {
allow_multiple_seconded: match mode {
ProspectiveParachainsMode::Enabled { .. } => true,
Expand Down Expand Up @@ -1726,6 +1754,19 @@ async fn kick_off_validation_work<Context>(
background_validation_tx: &mpsc::Sender<(Hash, ValidatedCandidateCommand)>,
attesting: AttestingData,
) -> Result<(), Error> {
// Do nothing if the local validator is disabled or not a validator at all
match rp_state.table_context.local_validator_is_disabled() {
Some(true) => {
gum::info!(target: LOG_TARGET, "We are disabled - don't kick off validation");
return Ok(())
},
Some(false) => {}, // we are not disabled - move on
None => {
gum::debug!(target: LOG_TARGET, "We are not a validator - don't kick off validation");
return Ok(())
},
}

let candidate_hash = attesting.candidate.hash();
if rp_state.issued_statements.contains(&candidate_hash) {
return Ok(())
Expand Down Expand Up @@ -1783,6 +1824,16 @@ async fn maybe_validate_and_import<Context>(
},
};

// Don't import statement if the sender is disabled
if rp_state.table_context.validator_is_disabled(&statement.validator_index()) {
gum::debug!(
target: LOG_TARGET,
sender_validator_idx = ?statement.validator_index(),
"Not importing statement because the sender is disabled"
);
return Ok(())
}

let res = import_statement(ctx, rp_state, &mut state.per_candidate, &statement).await;

// if we get an Error::RejectedByProspectiveParachains,
Expand Down Expand Up @@ -1944,6 +1995,13 @@ async fn handle_second_message<Context>(
Some(r) => r,
};

// Just return if the local validator is disabled. If we are here the local node should be a
// validator but defensively use `unwrap_or(false)` to continue processing in this case.
if rp_state.table_context.local_validator_is_disabled().unwrap_or(false) {
gum::warn!(target: LOG_TARGET, "Local validator is disabled. Don't validate and second");
return Ok(())
}

// Sanity check that candidate is from our assignment.
if Some(candidate.descriptor().para_id) != rp_state.assignment {
gum::debug!(
Expand Down Expand Up @@ -1990,6 +2048,7 @@ async fn handle_statement_message<Context>(
) -> Result<(), Error> {
let _timer = metrics.time_process_statement();

// Validator disabling is handled in `maybe_validate_and_import`
match maybe_validate_and_import(ctx, state, relay_parent, statement).await {
Err(Error::ValidationFailed(_)) => Ok(()),
Err(e) => Err(e),
Expand Down
Loading