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

02-client refactor: Adding VerifyClientMessage helper fn #1119

Merged
merged 26 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
73047c4
refactor: Adding VerifyClientMessage helper fn to ClientState
seantking Mar 15, 2022
628401d
Merge branch '02-client-refactor' into sean/issue#879-create-verify-h…
seantking Mar 21, 2022
8dd6dab
refactor: creating verifyHeader priv fn and respective test
seantking Mar 22, 2022
b04e491
refactor: adding initial test cases
seantking Mar 24, 2022
afb2ff5
refactor: add more test cases
seantking Mar 24, 2022
465b801
nit: move fns
seantking Mar 24, 2022
c6f9909
remove clientState var
seantking Mar 24, 2022
c5c5eb0
refactor: adding different val set test case
seantking Mar 24, 2022
f27b7b2
refactor: add test case for header with next height and diff validato…
seantking Mar 25, 2022
3676401
refactor: adding remaining test cases
seantking Mar 25, 2022
64dda21
chore: uncomment previous tests:
seantking Mar 25, 2022
76b600d
fix: chainA -> chainB
seantking Mar 25, 2022
76eec4f
chore: comment
seantking Mar 25, 2022
98310be
refactor: remove consState from api + fix tests
seantking Mar 28, 2022
ec00c35
refactor: add verifyHeader to clientState
seantking Mar 28, 2022
98599f8
Merge branch '02-client-refactor' into sean/issue#879-create-verify-h…
seantking Mar 28, 2022
7839463
Merge branch '02-client-refactor' into sean/issue#879-create-verify-h…
seantking Mar 28, 2022
0148f35
fix: incorret trusted validators for concensus state test
seantking Mar 28, 2022
795a4fc
Update modules/light-clients/07-tendermint/types/update_test.go
seantking Mar 28, 2022
7a1d046
chore: add comment
seantking Mar 28, 2022
926de94
fix: params
seantking Mar 28, 2022
36b5ebc
refactor: remove timestamp from api
seantking Mar 28, 2022
cbbf854
refactor: switch and type
seantking Mar 28, 2022
d42c9c0
Merge branch '02-client-refactor' into sean/issue#879-create-verify-h…
seantking Mar 28, 2022
fa4184f
fix: remove height+1
seantking Mar 28, 2022
4e5fca4
02-client refactor: add tests for verifyMisbehaviour (#1166)
colin-axner Mar 28, 2022
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
62 changes: 37 additions & 25 deletions modules/light-clients/07-tendermint/types/misbehaviour_handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,47 +32,62 @@ func (cs ClientState) CheckMisbehaviourAndUpdateState(
return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", misbehaviour, &Misbehaviour{})
}

// The status of the client is checked in 02-client
if err := cs.VerifyClientMessage(ctx, clientStore, cdc, tmMisbehaviour); err != nil {
return nil, err
}

cs.FrozenHeight = FrozenHeight

return &cs, nil
}

// verifyMisbehaviour determines whether or not two conflicting
// headers at the same height would have convinced the light client.
//
// NOTE: consensusState1 is the trusted consensus state that corresponds to the TrustedHeight
// of misbehaviour.Header1
// Similarly, consensusState2 is the trusted consensus state that corresponds
// to misbehaviour.Header2
// Misbehaviour sets frozen height to {0, 1} since it is only used as a boolean value (zero or non-zero).
func (cs *ClientState) verifyMisbehaviour(ctx sdk.Context, clientStore sdk.KVStore, cdc codec.BinaryCodec, misbehaviour *Misbehaviour) error {

// if heights are equal check that this is valid misbehaviour of a fork
// otherwise if heights are unequal check that this is valid misbehavior of BFT time violation
if tmMisbehaviour.Header1.GetHeight().EQ(tmMisbehaviour.Header2.GetHeight()) {
blockID1, err := tmtypes.BlockIDFromProto(&tmMisbehaviour.Header1.SignedHeader.Commit.BlockID)
if misbehaviour.Header1.GetHeight().EQ(misbehaviour.Header2.GetHeight()) {
blockID1, err := tmtypes.BlockIDFromProto(&misbehaviour.Header1.SignedHeader.Commit.BlockID)
if err != nil {
return nil, sdkerrors.Wrap(err, "invalid block ID from header 1 in misbehaviour")
return sdkerrors.Wrap(err, "invalid block ID from header 1 in misbehaviour")
}
blockID2, err := tmtypes.BlockIDFromProto(&tmMisbehaviour.Header2.SignedHeader.Commit.BlockID)

blockID2, err := tmtypes.BlockIDFromProto(&misbehaviour.Header2.SignedHeader.Commit.BlockID)
if err != nil {
return nil, sdkerrors.Wrap(err, "invalid block ID from header 2 in misbehaviour")
return sdkerrors.Wrap(err, "invalid block ID from header 2 in misbehaviour")
}

// Ensure that Commit Hashes are different
if bytes.Equal(blockID1.Hash, blockID2.Hash) {
return nil, sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers block hashes are equal")
return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers block hashes are equal")
}

} else {
// Header1 is at greater height than Header2, therefore Header1 time must be less than or equal to
// Header2 time in order to be valid misbehaviour (violation of monotonic time).
if tmMisbehaviour.Header1.SignedHeader.Header.Time.After(tmMisbehaviour.Header2.SignedHeader.Header.Time) {
return nil, sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers are not at same height and are monotonically increasing")
if misbehaviour.Header1.SignedHeader.Header.Time.After(misbehaviour.Header2.SignedHeader.Header.Time) {
return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers are not at same height and are monotonically increasing")
}
}

// Regardless of the type of misbehaviour, ensure that both headers are valid and would have been accepted by light-client

// Retrieve trusted consensus states for each Header in misbehaviour
// and unmarshal from clientStore

// Get consensus bytes from clientStore
tmConsensusState1, err := GetConsensusState(clientStore, cdc, tmMisbehaviour.Header1.TrustedHeight)
tmConsensusState1, err := GetConsensusState(clientStore, cdc, misbehaviour.Header1.TrustedHeight)
if err != nil {
return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header1 at TrustedHeight: %s", tmMisbehaviour.Header1)
return sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header1 at TrustedHeight: %s", misbehaviour.Header1.TrustedHeight)
}

// Get consensus bytes from clientStore
tmConsensusState2, err := GetConsensusState(clientStore, cdc, tmMisbehaviour.Header2.TrustedHeight)
tmConsensusState2, err := GetConsensusState(clientStore, cdc, misbehaviour.Header2.TrustedHeight)
if err != nil {
return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header2 at TrustedHeight: %s", tmMisbehaviour.Header2)
return sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header2 at TrustedHeight: %s", misbehaviour.Header2.TrustedHeight)
}

// Check the validity of the two conflicting headers against their respective
Expand All @@ -81,27 +96,24 @@ func (cs ClientState) CheckMisbehaviourAndUpdateState(
// misbehaviour.ValidateBasic by the client keeper and msg.ValidateBasic
// by the base application.
if err := checkMisbehaviourHeader(
&cs, tmConsensusState1, tmMisbehaviour.Header1, ctx.BlockTime(),
cs, tmConsensusState1, misbehaviour.Header1, ctx.BlockTime(),
); err != nil {
return nil, sdkerrors.Wrap(err, "verifying Header1 in Misbehaviour failed")
return sdkerrors.Wrap(err, "verifying Header1 in Misbehaviour failed")
}
if err := checkMisbehaviourHeader(
&cs, tmConsensusState2, tmMisbehaviour.Header2, ctx.BlockTime(),
cs, tmConsensusState2, misbehaviour.Header2, ctx.BlockTime(),
); err != nil {
return nil, sdkerrors.Wrap(err, "verifying Header2 in Misbehaviour failed")
return sdkerrors.Wrap(err, "verifying Header2 in Misbehaviour failed")
}

cs.FrozenHeight = FrozenHeight

return &cs, nil
return nil
}

// checkMisbehaviourHeader checks that a Header in Misbehaviour is valid misbehaviour given
// a trusted ConsensusState
func checkMisbehaviourHeader(
clientState *ClientState, consState *ConsensusState, header *Header, currentTimestamp time.Time,
) error {

tmTrustedValset, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators)
if err != nil {
return sdkerrors.Wrap(err, "trusted validator set is not tendermint validator set type")
Expand Down
Loading