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

chore: rename checkHeader to VerifyClientMessage #1109

Merged
merged 7 commits into from
Mar 16, 2022
56 changes: 42 additions & 14 deletions modules/light-clients/06-solomachine/types/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,50 @@ import (
// - the currently registered public key did not provide the update signature
func (cs ClientState) CheckHeaderAndUpdateState(
ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore,
header exported.ClientMessage,
msg exported.ClientMessage,
) (exported.ClientState, exported.ConsensusState, error) {
smHeader, ok := header.(*Header)
if err := cs.VerifyClientMessage(ctx, cdc, clientStore, msg); err != nil {
return nil, nil, err
}

// TODO: Remove this type assertion, replace with misbehaviour checking and update state
smHeader, ok := msg.(*Header)
if !ok {
return nil, nil, sdkerrors.Wrapf(
clienttypes.ErrInvalidHeader, "header type %T, expected %T", header, &Header{},
clienttypes.ErrInvalidHeader, "expected %T, got %T", &Header{}, msg,
)
}

if err := checkHeader(cdc, &cs, smHeader); err != nil {
return nil, nil, err
}

clientState, consensusState := update(&cs, smHeader)
return clientState, consensusState, nil
}

// checkHeader checks if the Solo Machine update signature is valid.
func checkHeader(cdc codec.BinaryCodec, clientState *ClientState, header *Header) error {
// VerifyClientMessage checks if the Solo Machine update signature(s) is valid.
func (cs ClientState) VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) error {
switch msg := clientMsg.(type) {
case *Header:
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
return cs.verifyHeader(ctx, cdc, clientStore, msg)
case *Misbehaviour:
return cs.verifyMisbehaviour(ctx, cdc, clientStore, msg)
default:
return sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type of %T or %T, got type %T", Header{}, Misbehaviour{}, msg)
}
}

func (cs ClientState) verifyHeader(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, header *Header) error {
// assert update sequence is current sequence
if header.Sequence != clientState.Sequence {
if header.Sequence != cs.Sequence {
return sdkerrors.Wrapf(
clienttypes.ErrInvalidHeader,
"header sequence does not match the client state sequence (%d != %d)", header.Sequence, clientState.Sequence,
"header sequence does not match the client state sequence (%d != %d)", header.Sequence, cs.Sequence,
)
}

// assert update timestamp is not less than current consensus state timestamp
if header.Timestamp < clientState.ConsensusState.Timestamp {
if header.Timestamp < cs.ConsensusState.Timestamp {
return sdkerrors.Wrapf(
clienttypes.ErrInvalidHeader,
"header timestamp is less than to the consensus state timestamp (%d < %d)", header.Timestamp, clientState.ConsensusState.Timestamp,
"header timestamp is less than to the consensus state timestamp (%d < %d)", header.Timestamp, cs.ConsensusState.Timestamp,
)
}

Expand All @@ -63,7 +75,7 @@ func checkHeader(cdc codec.BinaryCodec, clientState *ClientState, header *Header
return err
}

publicKey, err := clientState.ConsensusState.GetPubKey()
publicKey, err := cs.ConsensusState.GetPubKey()
if err != nil {
return err
}
Expand All @@ -75,6 +87,22 @@ func checkHeader(cdc codec.BinaryCodec, clientState *ClientState, header *Header
return nil
}

func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, misbehaviour *Misbehaviour) error {
// NOTE: a check that the misbehaviour message data are not equal is done by
// misbehaviour.ValidateBasic which is called by the 02-client keeper.
// verify first signature
if err := verifySignatureAndData(cdc, cs, misbehaviour, misbehaviour.SignatureOne); err != nil {
Copy link
Member Author

Choose a reason for hiding this comment

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

Thoughts on moving this function to be a method on ClientState? cc. @colin-axner @seantking

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm in favor! Nice suggestion

Copy link
Member Author

Choose a reason for hiding this comment

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

Will address this in a follow up :)

return sdkerrors.Wrap(err, "failed to verify signature one")
}

// verify second signature
if err := verifySignatureAndData(cdc, cs, misbehaviour, misbehaviour.SignatureTwo); err != nil {
return sdkerrors.Wrap(err, "failed to verify signature two")
}

return nil
}

// update the consensus state to the new public key and an incremented sequence
func update(clientState *ClientState, header *Header) (*ClientState, *ConsensusState) {
consensusState := &ConsensusState{
Expand Down
Loading