-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
IBC client - evidence module route #5305
Conversation
@cwgoes do we want to check every |
I'm a bit lost. If we ever detect misbehaviour (which requires submitting a transaction) we should freeze the client immediately. What are the two separate transactions involved in your scenario? |
TotalPower int64 `json:"total_power" yaml:"total_power"` | ||
// Misbehaviour contains an evidence that a | ||
type Misbehaviour struct { | ||
*Evidence |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does Misbehaviour contain ChainID
when Evidence already has ChainID
field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misbehaviour
contains only the ClientID
} | ||
if ev.ValidatorPower <= 0 { | ||
return sdk.ConvertError(errors.ErrInvalidEvidence(errors.DefaultCodespace, fmt.Sprintf("Invalid Validator Power: %d", ev.ValidatorPower))) | ||
if err := m.Evidence.ValidateBasic(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs to also check m.ChainID == m.Evidence.ChainID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment above
// | ||
// NOTE: In the first implementation, only Tendermint misbehaviour evidence is | ||
// supported. | ||
func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make sense to me. My understanding is that the client should be frozen if the entire chain breaks the consensus protocol. For example:
- ChainA is running light client of ChainB
- ChainB validator set commits 2 different blocks for the same height (violation of consensus protocol)
- Evidence of this violation is submitted to ChainA
- ChainA freezes light client of ChainB
The code here looks like it will freeze the client as soon as someone posts evidence of a single validator double signing. This doesn't make sense since it won't disrupt consensus, so long as validator power < 1/3 of total.
Thus, with code as is, a single slash event of a double-signing validator on chainB (which is still considered honest execution of Byzantine consensus protocol) will cause IBC client to freeze. Thus, a chainA no longer has any Byzantine tolerance for chainB; which doesn't seem like the intended behavior from looking at spec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the Evidence should be changed from embedding a single tendermint.DoubleVoteEvidence
to including two different block headers that got committed by ChainB's validatorSet but are for same height
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, i think i was the one to commit this mistake to the code in the first place 😆. Will put up PR for proposed fix, once i get an ACK that the problem i point out is correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further thinking here after prototyping solution:
-
The
Evidence
interface defined inx/evidence
isn't well suited to use here, since that is Evidence against a single malicious validator. Whereas I believe the Evidence that should freeze a ICS-02 client is evidence of a malicious chain. We should have some other primitive defined in x/ibc to deal with malicious chains. -
The overloading of the term Evidence to describe evidence against validators and evidence against chains is confusing. I think we should have a different word to talk about malicious chains and the associated proofs, (
Violation
maybe)?
Proposals:
A) evidence module is adjusted to handle both malicious-validator evidence and malicious-chain evidence
B) malicious-chain evidence types and functions are implemented within x/ibc
since that is the only place they will be used.
I'm partial to proposal B myself and removing any dependence of x/evidence
from x/ibc
for now, but interested to hear what others think. Note: validator-specific evidence isn't relevant in IBC for version 1.0.0, but will later be useful once we implement shared-security across chains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the Evidence should be changed from embedding a single tendermint.DoubleVoteEvidence to including two different block headers that got committed by ChainB's validatorSet but are for same height
yeah, that's how it is defined on the spec:
interface Evidence {
h1: Header
h2: Header
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Evidence interface defined in x/evidence isn't well suited to use here, since that is Evidence against a single malicious validator. Whereas I believe the Evidence that should freeze a ICS-02 client is evidence of a malicious chain. We should have some other primitive defined in x/ibc to deal with malicious chains.
A) evidence module is adjusted to handle both malicious-validator evidence and malicious-chain evidence
I think we should implement a general Evidence interface that only contains the following methods:
// Evidence defines the contract which concrete evidence types of misbehavior
// must implement.
type Evidence interface {
Route() string
Type() string
String() string
Hash() cmn.HexBytes
ValidateBasic() error
}
Probably the byzantine validator related methods from the current Evidence
interface should be abstracted into another interface:
// The consensus address of the malicious validator at time of infraction
GetConsensusAddress() sdk.ConsAddress
// Height at which the infraction occurred
GetHeight() int64
// The total power of the malicious validator at time of infraction
GetValidatorPower() int64
// The total validator set power at time of infraction
GetTotalPower() int64
And ICS02 should implement the Evidence interface from the spec (2 headers) as well as the general interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The overloading of the term
Evidence
to describe evidence against validators and evidence against chains is confusing. I think we should have a different word to talk about malicious chains and the associated proofs, (Violation
maybe)?
Agree, ICS02 introduces the term of a client Misbehaviour
, which is what I implemented in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Evidence interface defined in x/evidence isn't well suited to use here, since that is Evidence against a single malicious validator. Whereas I believe the Evidence that should freeze a ICS-02 client is evidence of a malicious chain. We should have some other primitive defined in x/ibc to deal with malicious chains.
A) evidence module is adjusted to handle both malicious-validator evidence and malicious-chain evidence
I think we should implement a general Evidence interface that only contains the following methods:
// Evidence defines the contract which concrete evidence types of misbehavior // must implement. type Evidence interface { Route() string Type() string String() string Hash() cmn.HexBytes ValidateBasic() error }Probably the byzantine validator related methods from the current
Evidence
interface should be abstracted into another interface:// The consensus address of the malicious validator at time of infraction GetConsensusAddress() sdk.ConsAddress // Height at which the infraction occurred GetHeight() int64 // The total power of the malicious validator at time of infraction GetValidatorPower() int64 // The total validator set power at time of infraction GetTotalPower() int64And ICS02 should implement the Evidence interface from the spec (2 headers) as well as the general interface
This approach seems OK to me. Conceivably other modules might want to handle such misbehaviour as well (e.g. if someone had purchased insurance that pays out if a validator set breaks safety).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conceivably other modules might want to handle such misbehaviour as well (e.g. if someone had purchased insurance that pays out if a validator set breaks safety).
afaik we haven't implemented slashing logic for this type of misbehaviour (if that's what you're referring with "handle such misbehaviour")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See responses to @AdityaSripal's comments
// | ||
// NOTE: In the first implementation, only Tendermint misbehaviour evidence is | ||
// supported. | ||
func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make sense to me. My understanding is that the client should be frozen if the entire chain breaks the consensus protocol. For example:
- ChainA is running light client of ChainB
- ChainB validator set commits 2 different blocks for the same height (violation of consensus protocol)
- Evidence of this violation is submitted to ChainA
- ChainA freezes light client of ChainB
The code here looks like it will freeze the client as soon as someone posts evidence of a single validator double signing. This doesn't make sense since it won't disrupt consensus, so long as validator power < 1/3 of total.
Thus, with code as is, a single slash event of a double-signing validator on chainB (which is still considered honest execution of Byzantine consensus protocol) will cause IBC client to freeze. Thus, a chainA no longer has any Byzantine tolerance for chainB; which doesn't seem like the intended behavior from looking at spec
Yes, this is right. Although it is also possible to choose thresholds other than 1/3 (perhaps gaining some extra precautionary safety at the expense of liveness), we should initially freeze the client if and only if two valid headers were committed at the same height.
// | ||
// NOTE: In the first implementation, only Tendermint misbehaviour evidence is | ||
// supported. | ||
func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further thinking here after prototyping solution:
- The
Evidence
interface defined inx/evidence
isn't well suited to use here, since that is Evidence against a single malicious validator. Whereas I believe the Evidence that should freeze a ICS-02 client is evidence of a malicious chain. We should have some other primitive defined in x/ibc to deal with malicious chains.- The overloading of the term Evidence to describe evidence against validators and evidence against chains is confusing. I think we should have a different word to talk about malicious chains and the associated proofs, (
Violation
maybe)?Proposals:
A) evidence module is adjusted to handle both malicious-validator evidence and malicious-chain evidence
B) malicious-chain evidence types and functions are implemented within
x/ibc
since that is the only place they will be used.I'm partial to proposal B myself and removing any dependence of
x/evidence
fromx/ibc
for now, but interested to hear what others think. Note: validator-specific evidence isn't relevant in IBC for version 1.0.0, but will later be useful once we implement shared-security across chains.
A new term might be a helpful differentiator. Malicious-chain evidence (or violation) types will be used by both the IBC on-chain light clients and Tendermint light clients (e.g. if you run gaiacli
in proper verification mode), so we should find a way to share the definitions between those two, ideally.
Co-Authored-By: Aditya <adityasripal@gmail.com>
@AdityaSripal should we block this PR until your fix is merged to |
ill make the PR against this branch since it already incorporates the interface from x/evidence. Don't think its a huge deal if this gets merged first. but would be slightly more convenient to block |
… fedekuze/ibc-evidence
…mos-sdk into fedekuze/ibc-evidence
moved to #5321 |
Targeted PR against correct branch (see CONTRIBUTING.md)
Linked to github-issue with discussion and accepted design OR link to spec that describes this work.
Wrote tests
Updated relevant documentation (
docs/
)Added a relevant changelog entry to the
Unreleased
section inCHANGELOG.md
Re-reviewed
Files changed
in the github PR explorerFor Admin Use: