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

refactor: require light clients to set initial client and consensus state #2936

Merged
merged 11 commits into from
Dec 15, 2022
Next Next commit
set the initial client and consensus state via the client state Initi…
…alize method. update godocs
  • Loading branch information
damiannolan committed Dec 14, 2022

Unverified

This user has not yet uploaded their public signing key.
commit ad72b805da2783270c08326863172597cd575248
15 changes: 5 additions & 10 deletions modules/core/02-client/keeper/client.go
Original file line number Diff line number Diff line change
@@ -10,8 +10,9 @@ import (
"github.com/cosmos/ibc-go/v6/modules/core/exported"
)

// CreateClient creates a new client state and populates it with a given consensus
// state as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#create
// CreateClient generates a new client identifier and isolated prefix store for the provided client state.
// The client state is responsible for setting any client-specific data in the store via the Initialize method.
// This includes the client state, initial consensus state and associated metadata.
func (k Keeper) CreateClient(
ctx sdk.Context, clientState exported.ClientState, consensusState exported.ConsensusState,
) (string, error) {
@@ -24,18 +25,12 @@ func (k Keeper) CreateClient(
}

clientID := k.GenerateClientIdentifier(ctx, clientState.ClientType())
clientStore := k.ClientStore(ctx, clientID)

k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())
damiannolan marked this conversation as resolved.
Show resolved Hide resolved

// verifies initial consensus state against client state and initializes client store with any client-specific metadata
// e.g. set ProcessedTime in Tendermint clients
if err := clientState.Initialize(ctx, k.cdc, k.ClientStore(ctx, clientID), consensusState); err != nil {
if err := clientState.Initialize(ctx, k.cdc, clientStore, consensusState); err != nil {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
return "", err
}

k.SetClientState(ctx, clientID, clientState)
k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState)

k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())

defer telemetry.IncrCounterWithLabels(
5 changes: 2 additions & 3 deletions modules/core/exported/client.go
Original file line number Diff line number Diff line change
@@ -59,9 +59,8 @@ type ClientState interface {
height Height,
) (uint64, error)

// Initialization function
// Clients must validate the initial consensus state, and may store any client-specific metadata
// necessary for correct light client operation
// Initialize is called upon client creation, it allows the client to perform validation on the initial consensus state and set the
// client state, consensus state and any client-specific metadata necessary for correct light client operation in the provided client store.
Initialize(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, consensusState ConsensusState) error

// VerifyMembership is a generic proof verification method which verifies a proof of the existence of a value at a given CommitmentPath at the specified height.
8 changes: 6 additions & 2 deletions modules/light-clients/06-solomachine/client_state.go
Original file line number Diff line number Diff line change
@@ -77,12 +77,16 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState {
panic("ZeroCustomFields is not implemented as the solo machine implementation does not support upgrades.")
}

// Initialize will check that initial consensus state is equal to the latest consensus state of the initial client.
func (cs ClientState) Initialize(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, consState exported.ConsensusState) error {
// Initialize checks that the initial consensus state is equal to the latest consensus state of the initial client and
// set the client state in the provided client store.
func (cs ClientState) Initialize(_ sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, consState exported.ConsensusState) error {
if !reflect.DeepEqual(cs.ConsensusState, consState) {
return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "consensus state in initial client does not equal initial consensus state. expected: %s, got: %s",
cs.ConsensusState, consState)
}

setClientState(clientStore, cdc, &cs)
colin-axner marked this conversation as resolved.
Show resolved Hide resolved

return nil
}

14 changes: 9 additions & 5 deletions modules/light-clients/07-tendermint/client_state.go
Original file line number Diff line number Diff line change
@@ -188,15 +188,19 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState {
}
}

// Initialize will check that initial consensus state is a Tendermint consensus state
// and will store ProcessedTime for initial consensus state as ctx.BlockTime()
func (cs ClientState) Initialize(ctx sdk.Context, _ codec.BinaryCodec, clientStore sdk.KVStore, consState exported.ConsensusState) error {
if _, ok := consState.(*ConsensusState); !ok {
// Initialize checks that the initial consensus state is a Tendermint consensus state and
// sets the client state, consensus state and associated metatdata in the provided client store.
damiannolan marked this conversation as resolved.
Show resolved Hide resolved
func (cs ClientState) Initialize(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, consState exported.ConsensusState) error {
consensusState, ok := consState.(*ConsensusState)
if !ok {
return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "invalid initial consensus state. expected type: %T, got: %T",
&ConsensusState{}, consState)
}
// set metadata for initial consensus state.

setClientState(clientStore, cdc, &cs)
setConsensusState(clientStore, cdc, consensusState, cs.GetLatestHeight())
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
setConsensusMetadata(ctx, clientStore, cs.GetLatestHeight())

return nil
}