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

add additional slash packet checks #619

Closed
wants to merge 12 commits into from
Closed

Conversation

MSalopek
Copy link
Contributor

@MSalopek MSalopek commented Dec 21, 2022

Please do not merge

Difftests are not working due to additional slash packet validation (ValidateBasic).

Description

Downtime slash packets will be dropped in HandleSlashPacket if a SlashAck already exists for a given chain and given validator. This prevents validators being spammed with downtime infractions without ever unjailing themselves.

Linked issues

EDIT: Partial fix for #544

Type of change

If you've checked more than one of the first three boxes, consider splitting this PR into multiple PRs!

  • Feature: Changes and/or adds code behavior, irrelevant to bug fixes

@MSalopek MSalopek marked this pull request as ready for review December 21, 2022 16:05
@MSalopek MSalopek force-pushed the masa/544-drop-outdated-slash branch 2 times, most recently from 8669281 to 1c3cc20 Compare December 21, 2022 16:06
// try to send slash packet for downtime infraction
// addr := ed25519.GenPrivKey().PubKey().Address()
// val := abci.Validator{Address: addr}
// consumerKeeper.QueueSlashPacket(s.consumerCtx(), val, 2, stakingtypes.Downtime)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sending these packets would cause an error in provider.OnRecvSlashPacket since the slash packet would be considered outdated.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was also running into problems with the tests in this file when first attempting to solve #546.

Imo we should change the test behavior instead of commenting out

Copy link
Contributor

Choose a reason for hiding this comment

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

Uncomment the tests and use the following reasoning to populate the valsetUpdateID of consumerKeeper.QueueSlashPacket:

// a downtime infraction identified at the current height
// has the infraction height set as follows (cf. SDK slashing module)
infractionHeight := s.consumerCtx().BlockHeight() - sdk.ValidatorUpdateDelay - 1
// for a double-sing infraction at consumer height H
// has the infraction height set as follows (cf. SDK evidence module)
infractionHeight := H - sdk.ValidatorUpdateDelay

For both downtime and double-signing, send SlashPackets using the following valsetUpdateID

infractionVSCid := consumerKeeper.GetHeightValsetUpdateID(s.consumerCtx(), uint64(infractionHeight))

tests/e2e/common.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/relay.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/relay.go Show resolved Hide resolved
x/ccv/provider/keeper/relay.go Show resolved Hide resolved
// try to send slash packet for downtime infraction
// addr := ed25519.GenPrivKey().PubKey().Address()
// val := abci.Validator{Address: addr}
// consumerKeeper.QueueSlashPacket(s.consumerCtx(), val, 2, stakingtypes.Downtime)
Copy link
Contributor

Choose a reason for hiding this comment

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

Uncomment the tests and use the following reasoning to populate the valsetUpdateID of consumerKeeper.QueueSlashPacket:

// a downtime infraction identified at the current height
// has the infraction height set as follows (cf. SDK slashing module)
infractionHeight := s.consumerCtx().BlockHeight() - sdk.ValidatorUpdateDelay - 1
// for a double-sing infraction at consumer height H
// has the infraction height set as follows (cf. SDK evidence module)
infractionHeight := H - sdk.ValidatorUpdateDelay

For both downtime and double-signing, send SlashPackets using the following valsetUpdateID

infractionVSCid := consumerKeeper.GetHeightValsetUpdateID(s.consumerCtx(), uint64(infractionHeight))

@MSalopek MSalopek marked this pull request as draft December 22, 2022 13:57
@MSalopek MSalopek force-pushed the masa/544-drop-outdated-slash branch 3 times, most recently from 7c2e475 to 7336dac Compare December 22, 2022 17:09
expSlash bool
vscID uint64
}{
{expSlash: true, vscID: vscIDs[0]},
{expSlash: true, vscID: vscIDs[1]},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smarshall-spitzbart I think this needs to be redone on my part. I think the point of the test got lost, right?

In this version, the second slash cannot be applied since the SlashAck for given validator already exists. The slash acks are consumed (deleted) in endblock.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm it's not completely clear what the original intention of the test was, considering the comment:

The test cases verify that only the unbonding tokens get slashed for the VSC ids mapping to the block heights before and during the undelegation otherwise not.

I think Marius may be more familiar with this functionality. @mpoke do you know what this test is validating?

@MSalopek MSalopek marked this pull request as ready for review December 22, 2022 17:20
Copy link
Contributor

@shaspitz shaspitz left a comment

Choose a reason for hiding this comment

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

Regarding slash acks as a mechanism to achieve

Drop SlashPackets for downtime infraction for the same validator that were received from the same consumer without the validator having the chance to Unjail itself.

(From #544)

Slash acks are appended for a particular chain only once that slash has been handled. Therefore I don't think slash acks work as a mechanism to achieve the closing criteria defined in the issue.

A malicious consumer could still send a bunch of downtime slash packets that are recv all in block N, those packets would all be queued during block N. During the end blocker of block N, one of the queued downtime slash packets could be handled, which would append the slash ack. Note that if the slash meter is negative in block N, no slash ack would be appended in block N. Even if a slash ack was appended in block N, this would only prevent spam until that slash ack is consumed, and the spam packets would only be dequeued if the slash ack exists at the time of handling.

To prevent spam, we need to be adding logic to ValidateSlashPacket, which runs before the slash packet is added to the queue.

x/ccv/provider/types/keys.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/keeper.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/keeper.go Show resolved Hide resolved
x/ccv/provider/keeper/relay.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/relay.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/relay.go Outdated Show resolved Hide resolved
x/ccv/provider/keeper/keeper.go Outdated Show resolved Hide resolved
@MSalopek
Copy link
Contributor Author

MSalopek commented Dec 23, 2022

Regarding slash acks as a mechanism to achieve

Drop SlashPackets for downtime infraction for the same validator that were received from the same consumer without the validator having the chance to Unjail itself.

(From #544)

Slash acks are appended for a particular chain only once that slash has been handled. Therefore I don't think slash acks work as a mechanism to achieve the closing criteria defined in the issue.

A malicious consumer could still send a bunch of downtime slash packets that are recv all in block N, those packets would all be queued during block N. During the end blocker of block N, one of the queued downtime slash packets could be handled, which would append the slash ack. Note that if the slash meter is negative in block N, no slash ack would be appended in block N. Even if a slash ack was appended in block N, this would only prevent spam until that slash ack is consumed, and the spam packets would only be dequeued if the slash ack exists at the time of handling.

To prevent spam, we need to be adding logic to ValidateSlashPacket, which runs before the slash packet is added to the queue.

After adding the requested changes I'm setting this to draft since difftests are failing because of the new functionality.

Current difftest do not account for the fact that LastDowntimeValsetUpdateId must increase monotonically and thus creates traces where the valsetUpdateId in the slash packet is less than LastDowntimeValsetUpdateId.

Updating difftests will take will take an unknown amount of time for me to handle.

@MSalopek MSalopek marked this pull request as draft December 23, 2022 13:44
@MSalopek MSalopek marked this pull request as ready for review December 23, 2022 17:49
@MSalopek MSalopek changed the title add initial outdated slash packet drop functionality add additional slash packet checks Dec 23, 2022
@MSalopek MSalopek marked this pull request as draft December 23, 2022 18:51
@MSalopek
Copy link
Contributor Author

MSalopek commented Dec 23, 2022

Please don't merge - difftests are not working due to additional slash packet validation (ValidateBasic).

Validate basic was removed, PR can be merged if need be.

@MSalopek MSalopek marked this pull request as ready for review January 3, 2023 11:17
@shaspitz
Copy link
Contributor

shaspitz commented Jan 3, 2023

If this PR will still close #544, it'll need to address the closing criteria of

RunSlashPacketData.ValidateBasic on receiving SlashPackets

Otherwise we can make that criteria it's own issue.

@MSalopek @mpoke I still do not understand how slash acks accomplish the following behavior in this PR

Drop SlashPackets for downtime infraction for the same validator that were received from the same consumer without the validator having the chance to Unjail itself.

AFAIK slash acks have nothing to do with unjailing, and slash acks are deleted once included in a VSC packet. It seems this comment still applies, and the current changes prevent spam only in a very small subset of cases, not the cases defined in the issue

@MSalopek
Copy link
Contributor Author

MSalopek commented Jan 3, 2023

If this PR will still close #544, it'll need to address the closing criteria of

RunSlashPacketData.ValidateBasic on receiving SlashPackets

Otherwise we can make that criteria it's own issue.

@MSalopek @mpoke I still do not understand how slash acks accomplish the following behavior in this PR

Drop SlashPackets for downtime infraction for the same validator that were received from the same consumer without the validator having the chance to Unjail itself.

AFAIK slash acks have nothing to do with unjailing, and slash acks are deleted once included in a VSC packet. It seems this comment still applies, and the current changes prevent spam only in a very small subset of cases, not the cases defined in the issue

Hi, thanks for the insight.

ValidateBasic was removed since it broke difftests in a way that is not super trivial to fix since it adds new requirements that need to be reflected in the difftest setup/trace generation.

This PR insures the validator has unjailed itself in case of multiple subsequent downtime requests from the same chain.

ValidateBasic addition can be tracked in the existing issue or in a new one if you prefer. I would prefer the current issue remain open, so no context is lost.

@mpoke
Copy link
Contributor

mpoke commented Jan 3, 2023

AFAIK slash acks have nothing to do with unjailing, and slash acks are deleted once included in a VSC packet.

@smarshall-spitzbart True. Which means that if two SlashPackets are received in the same block from the same chain requesting to slash the same validator for downtime, then the second packet is dropped. If the two packets are received in separate blocks, then the second packet will go through and the validator will be slashed. Thus, you are right Shawn. This doesn't fix the issue. @MSalopek

@MSalopek MSalopek marked this pull request as draft January 3, 2023 17:47
@MSalopek
Copy link
Contributor Author

MSalopek commented Jan 3, 2023

@mpoke @smarshall-spitzbart Thanks for your insights.

Drop SlashPackets for downtime infraction for the same validator that were received from the same consumer without the validator having the chance to Unjail itself.

After discussing with @smarshall-spitzbart it seems that this requirement cannot be fulfilled with basic checks that are currently proposed in this PR. We would need to keep additional state to achieve that, and that would need to be thoroughly tested.

The basic checks may still hold some value, but I am in favor of closing this PR as it stands now.

@mpoke
Copy link
Contributor

mpoke commented Jan 3, 2023

Closing and opening new issues: #635 and #634

@mpoke mpoke closed this Jan 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants