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

Enforce validator disabling in the runtime #1592

Closed
tdimitrov opened this issue Sep 15, 2023 · 8 comments · Fixed by #1863
Closed

Enforce validator disabling in the runtime #1592

tdimitrov opened this issue Sep 15, 2023 · 8 comments · Fixed by #1863
Assignees

Comments

@tdimitrov
Copy link
Contributor

Desired outcome

With the disabling strategy in place (#784 (comment)) the actual disabling needs to be enforced by the runtime. This means that the runtime should ignore the following data from disabled validators:

When a validator is disabled

Each candidate has got a relay parent. If a validator is disabled at this relay parent, we consider the validator disabled in the context of the candidate.
So if a candidate is included at height A and B and validator X is disabled at height A but re-enabled at height B we will ignore its votes in the first case and count them in the latter.

How data filtering will work

All votes/statements will be filtered in

Related to #784 (comment)

@tdimitrov
Copy link
Contributor Author

@eskimor @ordian @Overkillus this is the way I envision the disabling in the runtime. Please share your feedback.

@eskimor
Copy link
Member

eskimor commented Sep 16, 2023

Yes, but make sure to not include dead weight in the block. This means conceptually on block production you have to filter on block import we have to return an error if data from disabled validators are present.

To avoid divergence of code I would suggest to do the same filtering both on import and creation, but check the length in import before and after - if they differ: return an error.

This way it should be possible to maintain almost identical code paths (which prevents bugs from them getting out of sync). They would look like this (Rust inspired pseude code):

let len_pre_filter = statements.len();
filter_disabled(&mut statements);
let len_after_filter = statements.len();
if importing && len_pre_filter != len_after_filter {
  return Error(...)
}

@eskimor
Copy link
Member

eskimor commented Sep 16, 2023

For using the relay parent of the candidate as basis for disabled state. I know we said to do this to have consistency on the node side. In the runtime this seems annoying though .. .would make more sense to use the current block state here. Might make sense to discuss this one more time.

@eskimor
Copy link
Member

eskimor commented Sep 16, 2023

Actually did we even say this? What we could do is the following: A node is considered enabled on the node side, if we have at least one leaf in our view where it is enabled. Meaning, if there is at least one leaf where the validator is enabled we will not prematurely drop statements for example.

Different story in runtime and provisioner: Here we can (and should) drop statements based on the leaf we are currently operating on.

Potential problem: We don't have consensus here: Depending on our view we might filter votes, while other nodes do not. If then later on we learn about a better fork, which does not have the validator disabled then we dropped votes, which we should actually have kept.

Possible solution: No premature filtering at all: Subsystems accept votes from disabled notes, then for subsystems which operate with peer views, things stay easy: We only forward messages to nodes that have a leaf in their view where the validator is enabled.

For disputes, this does not work .... so I see why we decided on using the relay parent. Thoughts from your end?

@eskimor
Copy link
Member

eskimor commented Sep 16, 2023

What could work: Indeed no premature/early filtering, but the above and we don't participate in disputes if all negative votes are all from disabled nodes as in our currently active leaves. On leaf updates which cause disabled status by above definition to change to enabled again, we would need to make up for that missed participation.

This sounds like it could cause consensus issues, but in fact it should be fine: Once a single not disabled node participated, disabled status does not matter anymore. We don't need perfect consensus here.

@tdimitrov
Copy link
Contributor Author

Yes, but make sure to not include dead weight in the block.

I assume you talk about this filtering. If yes - I don't understand your idea. Why not filter the data just before the weights are calculated and ignore the disabled votes altogether? Maybe it is related to the two code paths of process_inherent_data.

For using the relay parent of the candidate as basis for disabled state.

Afair we didn't agree on anything. I'm proposing this because:

  1. The relay parent is finalized and all the instances of the runtime will have the same view in terms of which validators are disabled and which are not. This is not that important.
  2. We will avoid the situation where a candidate gets disabled in the middle of a fork and we need to reevaluate our decisions.

I am more worried about 2. What I mean:

BLOCK N -> Fork N+1 -> Fork N+2 -> Fork N+3 ...
(finalzied)

Let's assume we make a decision that in N+1 a dispute has concluded and in N+2 some validartor (which have alreadyu voted) gets disabled. We need to reevaluate the decision about the dispute? Or do something else?

Not considering if a validator is disabled in the current leaf has got its drawbacks - potential offenders (or buggy validators) can do wild things in the fork before they get disabled. In the general case it is just one block but in a dispute storm this window might get quite big.

@tdimitrov
Copy link
Contributor Author

tdimitrov commented Sep 18, 2023

Why not filter the data just before the weights are calculated and ignore the disabled votes altogether?

Yeah, this won't work.

EDIT: I wasn't aware that process_inherent_data was used to prepare inherent data and to validate it on block executioin. Now your idea makes sense to me.

tdimitrov added a commit that referenced this issue Nov 30, 2023
…s_inherent_data (#1863)

Fixes #1592

Please refer to the issue for details.

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
@Overkillus
Copy link
Contributor

Overkillus commented Dec 11, 2023

Based on the new updated validator disabling strategy Availability Bitfields and Dispute Statements are not touched within the runtime so #1863 fully closes the issue.

Just need to merge into feature branch and test holistically.

@Overkillus Overkillus added D1-medium Can be fixed by a coder with good Rust knowledge but little knowledge of the codebase. and removed D1-medium Can be fixed by a coder with good Rust knowledge but little knowledge of the codebase. labels Dec 11, 2023
tdimitrov added a commit that referenced this issue Jan 9, 2024
…s_inherent_data (#1863)

Fixes #1592

Please refer to the issue for details.

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
github-merge-queue bot pushed a commit that referenced this issue Jan 18, 2024
…s_inherent_data (#2889)

Backport of #1863 to
master

Extend candidate sanitation in paras_inherent by removing backing votes
from disabled validators. Check
#1592 for more details.

This change is related to the disabling strategy implementation
(#2226).

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
franciscoaguirre pushed a commit to paritytech/xcm that referenced this issue Jan 25, 2024
…s_inherent_data (#2889)

Backport of paritytech/polkadot-sdk#1863 to
master

Extend candidate sanitation in paras_inherent by removing backing votes
from disabled validators. Check
paritytech/polkadot-sdk#1592 for more details.

This change is related to the disabling strategy implementation
(paritytech/polkadot-sdk#2226).

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
bgallois pushed a commit to duniter/duniter-polkadot-sdk that referenced this issue Mar 25, 2024
…s_inherent_data (paritytech#2889)

Backport of paritytech#1863 to
master

Extend candidate sanitation in paras_inherent by removing backing votes
from disabled validators. Check
paritytech#1592 for more details.

This change is related to the disabling strategy implementation
(paritytech#2226).

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
Co-authored-by: Maciej <maciej.zyszkiewicz@parity.io>
serban300 pushed a commit to serban300/polkadot-sdk that referenced this issue Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Completed
3 participants