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

approval-voting: Make sure we always mark approved candidates approved in a different relay chain context #4153

Merged
merged 13 commits into from
Apr 18, 2024

Conversation

alexggh
Copy link
Contributor

@alexggh alexggh commented Apr 16, 2024

... see for more detail why this is needed
#4149 (comment)

TODO:

…d in a different relay chain context

... see for more detail why this is needed
#4149 (comment)

Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
@alexggh alexggh added R0-silent Changes should not be mentioned in any release notes T0-node This PR/Issue is related to the topic “node”. labels Apr 17, 2024
@alexggh alexggh marked this pull request as ready for review April 17, 2024 08:46
Copy link
Member

@ordian ordian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great find!

The root cause analysis seems on point, but I'm not sure about the fix itself. I mean it does fix this scenario, but I don't know if can create other issues or can be abused, so maybe it's a good idea to summon @rphmeier for discussion here.

polkadot/node/core/approval-voting/src/lib.rs Outdated Show resolved Hide resolved
@sandreim
Copy link
Contributor

Great find!

The root cause analysis seems on point, but I'm not sure about the fix itself. I mean it does fix this scenario, but I don't know if can create other issues or can be abused, so maybe it's a good idea to summon @rphmeier for discussion here.

The fix seems very subtle to me. I didn't think this too deep, but an alternative would be to approve it under all blocks known in CandidateEntry::block_assignments once it is approved on either of them.

@alexggh alexggh marked this pull request as draft April 17, 2024 14:31
@alexggh
Copy link
Contributor Author

alexggh commented Apr 17, 2024

Great find!
The root cause analysis seems on point, but I'm not sure about the fix itself. I mean it does fix this scenario, but I don't know if can create other issues or can be abused, so maybe it's a good idea to summon @rphmeier for discussion here.

The fix seems very subtle to me. I didn't think this too deep, but an alternative would be to approve it under all blocks known in CandidateEntry::block_assignments once it is approved on either of them.

@sandreim convinced me offline that this ^^^ is the proper fix, will come back with a new version, marking the PR as draft until I get that done.

@sandreim
Copy link
Contributor

Just discussing this with @eskimor . This might reduce security slightly, since attackers get more chances(as amount of forks) to have all the bad guys in tranche0 and approve something invalid. CC @burdges

@alexggh
Copy link
Contributor Author

alexggh commented Apr 17, 2024

Just discussing this with @eskimor . This might reduce security slightly, since attackers get more chances(as amount of forks) to have all the bad guys in tranche0 and approve something invalid. CC @burdges

You mean if we mark the candidate approved in other blocks when it got approved in one of the fork, yeah that's right we would increase the chances of an attacker.
We actually need to call everything in advance_approval_state which would use the assignments on R1 with the approvals we received on all forks(R1 + R1') and mark the candidate approved on R1 only if all the assignments on R1 had been properly covered. So, that is actually what this PR in this form does.

Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
@alexggh
Copy link
Contributor Author

alexggh commented Apr 18, 2024

Ended up making this fix more explicit by scheduling a waking up on forked relay blocks, only if there is no wake up scheduled and if the validator in question already has an assignment on it.

Additionally, improved the unittest to test the exact scenario I described here: #4149 (comment).

@sandreim @ordian let me know what you think. Marking it as ready for re-review.

@alexggh alexggh marked this pull request as ready for review April 18, 2024 07:05
Copy link
Contributor

@sandreim sandreim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alexggh this much better now 👍🏼

polkadot/node/core/approval-voting/src/lib.rs Outdated Show resolved Hide resolved
polkadot/node/core/approval-voting/src/lib.rs Outdated Show resolved Hide resolved
polkadot/node/core/approval-voting/src/lib.rs Outdated Show resolved Hide resolved
polkadot/node/core/approval-voting/src/lib.rs Outdated Show resolved Hide resolved
polkadot/node/core/approval-voting/src/lib.rs Outdated Show resolved Hide resolved
alexggh and others added 4 commits April 18, 2024 13:21
Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com>
Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Copy link
Member

@ordian ordian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good to me. Nice work!

polkadot/node/core/approval-voting/src/tests.rs Outdated Show resolved Hide resolved
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
@alexggh alexggh enabled auto-merge April 18, 2024 15:19
@alexggh alexggh added this pull request to the merge queue Apr 18, 2024
Merged via the queue into master with commit 37e338f Apr 18, 2024
129 of 137 checks passed
@alexggh alexggh deleted the alexggh/fix_no_shows branch April 18, 2024 16:21
@burdges
Copy link

burdges commented May 31, 2024

I've no idea how I missed this one, so..

We do assignments using private VRFs of the relay chain VRF when the candidate gets included, so candidates have different assignments based upon when they're included.

We should not give adversaries more control over the selection of approval checkers, but there are roughly two axies here:

  1. enough adversarial assignments - controls when adversaries can launch attacks, but adversaries can already control this by simply waiting, so no new concerns here.
  2. few honest assignments - controls when adversaries could win in their attacks, so adversaries should not gain new influence here.

Abstractly, once assignments exist then they should be executed, possibly creating remote disputes. In principle, if relay block R includes parablock X then finality for R should ideally wait upon all assignments for X on all relay chain forks, but how much does this matter?

We've always worried about 2 in the context of an adversary making two forks, one which includes the core and one which abandons the core, with which the adversary kills the including fork if approval chekers look unfavorable. In this, the abandonment fork could safely finalize early, but then the assignments should still occur on the inclusion fork, and create a remote dispute. As the adversay loses temporarily, we ensure they exaust all the dots before winning.

In theory, adversaries could include the same candidate in many relay chain forks, and then advance and finalize only the fork where we assign too few honest checkers. We never really covered this case in the security analysis, but does the adversary have enough checkers?

As an off the cuff approximation, an adversary needs core collisions in multi-sets given by their own tranche zero assignments. We have p = num_samples / num_cores odds of a fixed core being inside a fixed validator's tranche zero, so then the number of adversarial validators like this one has the Binomial distribution B(n=num_validators/3, p) and num_cores ways that could happen. As k = needed_approvals-1 > n p we have Pr(X ≥ k) = F(n-k; n, 1-p) < exp[ -2n (p - k/n)^2 ].

We'll take p = E/num_validators >?< needed_approvals/num_validators using the usual approximations discussed in #640, so then p - k/n >?< (2/3) (k/n). If >?< is = then Pr(X ≥ k) < exp[ - 8/9 n (k/n)^2 ].

I remembered much smaller numbers there, so maybe I've screwed up the above, but this suggests adversaries have simple attack windows like 1% of the time, but the multi-attack windows still strink rapidly in size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
R0-silent Changes should not be mentioned in any release notes T0-node This PR/Issue is related to the topic “node”.
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

4 participants