diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fb2e6ad9fb..c970fd44340 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
 * (modules/core/02-client) [\#1196](https://github.com/cosmos/ibc-go/pull/1196) Adding VerifyClientMessage to ClientState interface. 
 * (modules/core/02-client) [\#1198](https://github.com/cosmos/ibc-go/pull/1198) Adding UpdateStateOnMisbehaviour to ClientState interface. 
 * (modules/core/02-client) [\#1170](https://github.com/cosmos/ibc-go/pull/1170) Updating `ClientUpdateProposal` to set client state in lightclient implementations `CheckSubstituteAndUpdateState` methods.
+* (modules/core/exported) [\#1206](https://github.com/cosmos/ibc-go/pull/1206) Adding new method `UpdateState` to `ClientState` interface.
 
 
 ### Features
diff --git a/modules/core/02-client/legacy/v100/solomachine.go b/modules/core/02-client/legacy/v100/solomachine.go
index 24744c3fcbd..3696c89a458 100644
--- a/modules/core/02-client/legacy/v100/solomachine.go
+++ b/modules/core/02-client/legacy/v100/solomachine.go
@@ -102,6 +102,11 @@ func (cs *ClientState) VerifyClientMessage(
 	panic("legacy solo machine is deprecated!")
 }
 
+// UpdateState panis!
+func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) error {
+	panic("legacy solo machine is deprecated!")
+}
+
 // CheckHeaderAndUpdateState panics!
 func (cs *ClientState) CheckHeaderAndUpdateState(
 	_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage,
diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go
index 225f668fdd7..9490e633984 100644
--- a/modules/core/exported/client.go
+++ b/modules/core/exported/client.go
@@ -58,6 +58,10 @@ type ClientState interface {
 	// VerifyClientMessage verifies a ClientMessage. A ClientMessage could be a Header, Misbehaviour, or batch update.
 	VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) error
 
+	// UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. 
+	// An error is returned if ClientMessage is of type Misbehaviour
+	UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) error
+
 	// Update and Misbehaviour functions
 	CheckHeaderAndUpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) (ClientState, ConsensusState, error)
 	CheckMisbehaviourAndUpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) (ClientState, error)
diff --git a/modules/light-clients/06-solomachine/types/update.go b/modules/light-clients/06-solomachine/types/update.go
index 9379a622897..2bf3ea64f35 100644
--- a/modules/light-clients/06-solomachine/types/update.go
+++ b/modules/light-clients/06-solomachine/types/update.go
@@ -30,7 +30,13 @@ func (cs ClientState) CheckHeaderAndUpdateState(
 		return &cs, cs.ConsensusState, nil
 	}
 
-	return cs.UpdateState(ctx, cdc, clientStore, msg)
+	if err := cs.UpdateState(ctx, cdc, clientStore, msg); err != nil {
+		return nil, nil, err
+	}
+
+	newClientState := clienttypes.MustUnmarshalClientState(cdc, clientStore.Get(host.ClientStateKey())).(*ClientState)
+
+	return newClientState, newClientState.ConsensusState, nil
 }
 
 // VerifyClientMessage introspects the provided ClientMessage and checks its validity
@@ -104,10 +110,10 @@ func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec,
 }
 
 // UpdateState updates the consensus state to the new public key and an incremented sequence.
-func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) (exported.ClientState, exported.ConsensusState, error) {
+func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) error {
 	smHeader, ok := clientMsg.(*Header)
 	if !ok {
-		return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected %T got %T", Header{}, clientMsg)
+		return sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected %T got %T", Header{}, clientMsg)
 	}
 
 	// create new solomachine ConsensusState
@@ -122,7 +128,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client
 
 	clientStore.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(cdc, &cs))
 
-	return &cs, consensusState, nil
+	return nil
 }
 
 // CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false
diff --git a/modules/light-clients/06-solomachine/types/update_test.go b/modules/light-clients/06-solomachine/types/update_test.go
index 53b6f014890..0078c4718df 100644
--- a/modules/light-clients/06-solomachine/types/update_test.go
+++ b/modules/light-clients/06-solomachine/types/update_test.go
@@ -612,11 +612,7 @@ func (suite *SoloMachineTestSuite) TestUpdateState() {
 			suite.Run(tc.name, func() {
 				tc.setup() // setup test
 
-				// TODO: remove casting when 'UpdateState' is an interface function.
-				clientState, ok := clientState.(*types.ClientState)
-				suite.Require().True(ok)
-
-				_, _, err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg)
+				err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg)
 
 				if tc.expPass {
 					suite.Require().NoError(err)
diff --git a/modules/light-clients/07-tendermint/types/update.go b/modules/light-clients/07-tendermint/types/update.go
index ecd88312882..5b854730992 100644
--- a/modules/light-clients/07-tendermint/types/update.go
+++ b/modules/light-clients/07-tendermint/types/update.go
@@ -90,11 +90,14 @@ func (cs ClientState) CheckHeaderAndUpdateState(
 		return &cs, consState, nil
 	}
 
-	newClientState, consensusState, err := cs.UpdateState(ctx, cdc, clientStore, tmHeader)
-	if err != nil {
+	if err := cs.UpdateState(ctx, cdc, clientStore, tmHeader); err != nil {
 		return nil, nil, err
 	}
-	return newClientState, consensusState, nil
+
+	newClientState := clienttypes.MustUnmarshalClientState(cdc, clientStore.Get(host.ClientStateKey()))
+	newConsensusState := clienttypes.MustUnmarshalConsensusState(cdc, clientStore.Get(host.ConsensusStateKey(header.GetHeight())))
+
+	return newClientState, newConsensusState, nil
 }
 
 // checkTrustedHeader checks that consensus state matches trusted fields of Header
@@ -238,16 +241,16 @@ func (cs *ClientState) verifyHeader(
 // UpdateState must only be used to update within a single revision, thus header revision number and trusted height's revision
 // number must be the same. To update to a new revision, use a separate upgrade path
 // UpdateState will prune the oldest consensus state if it is expired.
-func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) (*ClientState, *ConsensusState, error) {
+func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) error {
 	header, ok := clientMsg.(*Header)
 	if !ok {
-		return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", &Header{}, header)
+		return sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", &Header{}, header)
 	}
 
 	// check for duplicate update
 	if consensusState, _ := GetConsensusState(clientStore, cdc, header.GetHeight()); consensusState != nil {
 		// perform no-op
-		return &cs, consensusState, nil
+		return nil
 	}
 
 	cs.pruneOldestConsensusState(ctx, cdc, clientStore)
@@ -267,7 +270,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client
 	setConsensusState(clientStore, cdc, consensusState, header.GetHeight())
 	setConsensusMetadata(ctx, clientStore, header.GetHeight())
 
-	return &cs, consensusState, nil
+	return nil
 }
 
 // pruneOldestConsensusState will retrieve the earliest consensus state for this clientID and check if it is expired. If it is,
diff --git a/modules/light-clients/07-tendermint/types/update_test.go b/modules/light-clients/07-tendermint/types/update_test.go
index 4f9648bd74a..bdc38e2486c 100644
--- a/modules/light-clients/07-tendermint/types/update_test.go
+++ b/modules/light-clients/07-tendermint/types/update_test.go
@@ -511,12 +511,8 @@ func (suite *TendermintTestSuite) TestUpdateState() {
 
 			clientState := path.EndpointA.GetClientState()
 
-			// TODO: remove casting when 'UpdateState' is an interface function.
-			tmClientState, ok := clientState.(*types.ClientState)
-			suite.Require().True(ok)
-
 			clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID)
-			_, _, err = tmClientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage)
+			err = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage)
 
 			if tc.expPass {
 				suite.Require().NoError(err)