Skip to content

Commit

Permalink
x/ibc: migrate 02-client to use proto encoded/decoded client states (#…
Browse files Browse the repository at this point in the history
…6948)

* begin migration

* make client state a pointer

* fix build

* fixes from self review and rename cdctypes -> codectypes

* add godoc
  • Loading branch information
colin-axner authored Aug 5, 2020
1 parent 392121e commit 1a531cb
Show file tree
Hide file tree
Showing 22 changed files with 157 additions and 94 deletions.
4 changes: 2 additions & 2 deletions x/ibc-transfer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/module"
Expand Down Expand Up @@ -79,7 +79,7 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command {
}

// RegisterInterfaces registers module concrete types into protobuf Any.
func (AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
types.RegisterInterfaces(registry)
}

Expand Down
6 changes: 3 additions & 3 deletions x/ibc-transfer/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package types

import (
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// RegisterInterfaces register the ibc transfer module interfaces to protobuf
// Any.
func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations((*sdk.Msg)(nil), &MsgTransfer{})
}

Expand All @@ -18,5 +18,5 @@ var (
//
// The actual codec used for serialization should be provided to x/ibc-transfer and
// defined at the application level.
ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry())
ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
)
8 changes: 4 additions & 4 deletions x/ibc/02-client/keeper/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
}
var (
updateHeader ibctmtypes.Header
clientState ibctmtypes.ClientState
clientState *ibctmtypes.ClientState
)

cases := []struct {
Expand Down Expand Up @@ -128,7 +128,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
return nil
}, false},
{"frozen client before update", func() error {
clientState = ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
clientState = &ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
suite.keeper.SetClientType(suite.ctx, testClientID, exported.Tendermint)
updateHeader = createFutureUpdateFn(suite)
Expand Down Expand Up @@ -309,7 +309,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
ClientID: testClientID,
},
func() error {
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
clientState := &ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
return nil
},
Expand All @@ -324,7 +324,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
ClientID: testClientID,
},
func() error {
clientState := ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
clientState := &ibctmtypes.ClientState{FrozenHeight: 1, LatestHeight: testClientHeight}
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
return nil
},
Expand Down
49 changes: 49 additions & 0 deletions x/ibc/02-client/keeper/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package keeper

import (
"fmt"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
)

// MustUnmarshalClientState attempts to decode and return an ClientState object from
// raw encoded bytes. It panics on error.
func (k Keeper) MustUnmarshalClientState(bz []byte) exported.ClientState {
clientState, err := k.UnmarshalClientState(bz)
if err != nil {
panic(fmt.Errorf("failed to decode client state: %w", err))
}

return clientState
}

// MustMarshalClientState attempts to encode an ClientState object and returns the
// raw encoded bytes. It panics on error.
func (k Keeper) MustMarshalClientState(clientState exported.ClientState) []byte {
bz, err := k.MarshalClientState(clientState)
if err != nil {
panic(fmt.Errorf("failed to encode client state: %w", err))
}

return bz
}

// MarshalClientState marshals an ClientState interface. If the given type implements
// the Marshaler interface, it is treated as a Proto-defined message and
// serialized that way.
func (k Keeper) MarshalClientState(clientStateI exported.ClientState) ([]byte, error) {
return codec.MarshalAny(k.cdc, clientStateI)
}

// UnmarshalClientState returns an ClientState interface from raw encoded clientState
// bytes of a Proto-based ClientState type. An error is returned upon decoding
// failure.
func (k Keeper) UnmarshalClientState(bz []byte) (exported.ClientState, error) {
var clientState exported.ClientState
if err := codec.UnmarshalAny(k.cdc, &clientState, bz); err != nil {
return nil, err
}

return clientState, nil
}
21 changes: 10 additions & 11 deletions x/ibc/02-client/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ import (
// state information
type Keeper struct {
storeKey sdk.StoreKey
cdc *codec.Codec
cdc codec.BinaryMarshaler
aminoCdc *codec.Codec
stakingKeeper types.StakingKeeper
}

// NewKeeper creates a new NewKeeper instance
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, sk types.StakingKeeper) Keeper {
func NewKeeper(cdc codec.BinaryMarshaler, aminoCdc *codec.Codec, key sdk.StoreKey, sk types.StakingKeeper) Keeper {
return Keeper{
storeKey: key,
cdc: cdc,
aminoCdc: aminoCdc,
stakingKeeper: sk,
}
}
Expand All @@ -48,16 +50,14 @@ func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (exported.Clien
return nil, false
}

var clientState exported.ClientState
k.cdc.MustUnmarshalBinaryBare(bz, &clientState)
clientState := k.MustUnmarshalClientState(bz)
return clientState, true
}

// SetClientState sets a particular Client to the store
func (k Keeper) SetClientState(ctx sdk.Context, clientID string, clientState exported.ClientState) {
store := k.ClientStore(ctx, clientID)
bz := k.cdc.MustMarshalBinaryBare(clientState)
store.Set(host.KeyClientState(), bz)
store.Set(host.KeyClientState(), k.MustMarshalClientState(clientState))
}

// GetClientType gets the consensus type for a specific client
Expand Down Expand Up @@ -86,15 +86,15 @@ func (k Keeper) GetClientConsensusState(ctx sdk.Context, clientID string, height
}

var consensusState exported.ConsensusState
k.cdc.MustUnmarshalBinaryBare(bz, &consensusState)
k.aminoCdc.MustUnmarshalBinaryBare(bz, &consensusState)
return consensusState, true
}

// SetClientConsensusState sets a ConsensusState to a particular client at the given
// height
func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height uint64, consensusState exported.ConsensusState) {
store := k.ClientStore(ctx, clientID)
bz := k.cdc.MustMarshalBinaryBare(consensusState)
bz := k.aminoCdc.MustMarshalBinaryBare(consensusState)
store.Set(host.KeyConsensusState(height), bz)
}

Expand All @@ -114,7 +114,7 @@ func (k Keeper) IterateConsensusStates(ctx sdk.Context, cb func(clientID string,
}
clientID := keySplit[1]
var consensusState exported.ConsensusState
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &consensusState)
k.aminoCdc.MustUnmarshalBinaryBare(iterator.Value(), &consensusState)

if cb(clientID, consensusState) {
break
Expand Down Expand Up @@ -233,8 +233,7 @@ func (k Keeper) IterateClients(ctx sdk.Context, cb func(clientID string, cs expo
if keySplit[len(keySplit)-1] != "clientState" {
continue
}
var clientState exported.ClientState
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &clientState)
clientState := k.MustUnmarshalClientState(iterator.Value())

// key is ibc/{clientid}/clientState
// Thus, keySplit[1] is clientID
Expand Down
6 changes: 4 additions & 2 deletions x/ibc/02-client/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const (
type KeeperTestSuite struct {
suite.Suite

cdc *codec.Codec
cdc codec.Marshaler
aminoCdc *codec.Codec
ctx sdk.Context
keeper *keeper.Keeper
consensusState ibctmtypes.ConsensusState
Expand All @@ -56,7 +57,8 @@ func (suite *KeeperTestSuite) SetupTest() {
now2 := suite.now.Add(time.Hour)
app := simapp.Setup(isCheckTx)

suite.cdc = app.Codec()
suite.cdc = app.AppCodec()
suite.aminoCdc = app.Codec()
suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{Height: testClientHeight, ChainID: testClientID, Time: now2})
suite.keeper = &app.IBCKeeper.ClientKeeper
suite.privVal = tmtypes.NewMockPV()
Expand Down
38 changes: 27 additions & 11 deletions x/ibc/02-client/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,41 @@ package types

import (
"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
)

// SubModuleCdc defines the IBC client codec.
var SubModuleCdc *codec.Codec

func init() {
SubModuleCdc = codec.New()
cryptocodec.RegisterCrypto(SubModuleCdc)
RegisterCodec(SubModuleCdc)
}

// RegisterCodec registers the IBC client interfaces and types
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*exported.ClientState)(nil), nil)
cdc.RegisterInterface((*exported.ClientState)(nil), nil) // remove after genesis migration
cdc.RegisterInterface((*exported.MsgCreateClient)(nil), nil)
cdc.RegisterInterface((*exported.MsgUpdateClient)(nil), nil)
cdc.RegisterInterface((*exported.ConsensusState)(nil), nil)
cdc.RegisterInterface((*exported.Header)(nil), nil)
cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil)
}

// RegisterInterfaces registers the client interfaces to protobuf Any.
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterInterface(
"cosmos_sdk.ibc.v1.client.ClientState",
(*exported.ClientState)(nil),
)
}

var (
amino = codec.New()

// SubModuleCdc references the global x/ibc/02-client module codec. Note, the codec should
// ONLY be used in certain instances of tests and for JSON encoding as Amino is
// still used for that purpose.
//
// The actual codec used for serialization should be provided to x/ibc/02-client and
// defined at the application level.
SubModuleCdc = codec.NewHybridCodec(amino, codectypes.NewInterfaceRegistry())
)

func init() {
RegisterCodec(amino)
amino.Seal()
}
6 changes: 3 additions & 3 deletions x/ibc/03-connection/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package types

import (
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// RegisterInterfaces register the ibc interfaces submodule implementations to protobuf
// Any.
func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgConnectionOpenInit{},
Expand All @@ -24,5 +24,5 @@ var (
//
// The actual codec used for serialization should be provided to x/ibc/03-connectionl and
// defined at the application level.
SubModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry())
SubModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
)
6 changes: 3 additions & 3 deletions x/ibc/04-channel/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package types

import (
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// RegisterInterfaces register the ibc channel submodule interfaces to protobuf
// Any.
func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgChannelOpenInit{},
Expand All @@ -28,4 +28,4 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
//
// The actual codec used for serialization should be provided to x/ibc/04-channel and
// defined at the application level.
var SubModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry())
var SubModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
4 changes: 2 additions & 2 deletions x/ibc/07-tendermint/misbehaviour.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func CheckMisbehaviourAndUpdateState(
) (clientexported.ClientState, error) {

// cast the interface to specific types before checking for misbehaviour
tmClientState, ok := clientState.(types.ClientState)
tmClientState, ok := clientState.(*types.ClientState)
if !ok {
return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", types.ClientState{}, clientState)
}
Expand Down Expand Up @@ -59,7 +59,7 @@ func CheckMisbehaviourAndUpdateState(

// checkMisbehaviour checks if the evidence provided is a valid light client misbehaviour
func checkMisbehaviour(
clientState types.ClientState, consensusState types.ConsensusState, evidence types.Evidence,
clientState *types.ClientState, consensusState types.ConsensusState, evidence types.Evidence,
height uint64, currentTimestamp time.Time, consensusParams *abci.ConsensusParams,
) error {
// calculate the age of the misbehaviour evidence
Expand Down
8 changes: 4 additions & 4 deletions x/ibc/07-tendermint/types/client_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import (
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
)

var _ clientexported.ClientState = ClientState{}
var _ clientexported.ClientState = (*ClientState)(nil)

// InitializeFromMsg creates a tendermint client state from a CreateClientMsg
func InitializeFromMsg(msg *MsgCreateClient) ClientState {
func InitializeFromMsg(msg *MsgCreateClient) *ClientState {
return NewClientState(msg.Header.ChainID, msg.TrustLevel,
msg.TrustingPeriod, msg.UnbondingPeriod, msg.MaxClockDrift,
uint64(msg.Header.Height), msg.ProofSpecs,
Expand All @@ -36,8 +36,8 @@ func NewClientState(
chainID string, trustLevel Fraction,
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
latestHeight uint64, specs []*ics23.ProofSpec,
) ClientState {
return ClientState{
) *ClientState {
return &ClientState{
ChainID: chainID,
TrustLevel: trustLevel,
TrustingPeriod: trustingPeriod,
Expand Down
Loading

0 comments on commit 1a531cb

Please sign in to comment.