Skip to content

Commit

Permalink
ibc: client params allowlist (cosmos#7855)
Browse files Browse the repository at this point in the history
* ibc: client params allowlist

* genesis and gRPC

* client

* lint

* spec

* fixes

* validate localhost client

* move client types back to exported

* update genesis

* sort clients by id
  • Loading branch information
fedekunze authored Nov 11, 2020
1 parent 116d046 commit 136f3ad
Show file tree
Hide file tree
Showing 72 changed files with 4,453 additions and 3,230 deletions.
91 changes: 6 additions & 85 deletions proto/ibc/core/client/v1/client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,91 +6,6 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";

// Msg defines the ibc/client Msg service.
service Msg {
// CreateClient defines a rpc handler method for MsgCreateClient.
rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse);

// UpdateClient defines a rpc handler method for MsgUpdateClient.
rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse);

// UpgradeClient defines a rpc handler method for MsgUpgradeClient.
rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse);

// SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour.
rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse);
}

// MsgCreateClient defines a message to create an IBC client
message MsgCreateClient {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// light client state
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
// consensus state associated with the client that corresponds to a given
// height.
google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
// signer address
string signer = 4;
}

// MsgCreateClientResponse defines the Msg/CreateClient response type.
message MsgCreateClientResponse { }

// MsgUpdateClient defines an sdk.Msg to update a IBC client state using
// the given header.
message MsgUpdateClient {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// header to update the light client
google.protobuf.Any header = 2;
// signer address
string signer = 3;
}

// MsgUpdateClientResponse defines the Msg/UpdateClient response type.
message MsgUpdateClientResponse { }

// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state
message MsgUpgradeClient {
// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// upgraded client state
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
// height at which old chain halts and upgrades (i.e last block executed)
Height upgrade_height = 3 [(gogoproto.moretags) = "yaml:\"upgrade_height\""];
// proof that old chain committed to new client
bytes proof_upgrade = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""];
// signer address
string signer = 5;
}

// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type.
message MsgUpgradeClientResponse { }

// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for
// light client misbehaviour.
message MsgSubmitMisbehaviour {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// misbehaviour used for freezing the light client
google.protobuf.Any misbehaviour = 2;
// signer address
string signer = 3;
}

// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response type.
message MsgSubmitMisbehaviourResponse { }

// IdentifiedClientState defines a client state with an additional client
// identifier field.
message IdentifiedClientState {
Expand Down Expand Up @@ -151,3 +66,9 @@ message Height {
// the height within the given version
uint64 version_height = 2 [(gogoproto.moretags) = "yaml:\"version_height\""];
}

// Params defines the set of IBC light client parameters.
message Params {
// allowed_clients defines the list of allowed client state types.
repeated string allowed_clients = 1 [(gogoproto.moretags) = "yaml:\"allowed_clients\""];
}
8 changes: 6 additions & 2 deletions proto/ibc/core/client/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ import "gogoproto/gogo.proto";
// GenesisState defines the ibc client submodule's genesis state.
message GenesisState {
// client states with their corresponding identifiers
repeated IdentifiedClientState clients = 1 [(gogoproto.nullable) = false];
repeated IdentifiedClientState clients = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "IdentifiedClientStates"
];
// consensus states from each client
repeated ClientConsensusStates clients_consensus = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "ClientsConsensusStates",
(gogoproto.moretags) = "yaml:\"clients_consensus\""
];
Params params = 3 [ (gogoproto.nullable) = false];
// create localhost on initialization
bool create_localhost = 3 [(gogoproto.moretags) = "yaml:\"create_localhost\""];
bool create_localhost = 4 [(gogoproto.moretags) = "yaml:\"create_localhost\""];
}
19 changes: 18 additions & 1 deletion proto/ibc/core/client/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ service Query {
rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) {
option (google.api.http).get = "/ibc/core/client/v1beta1/consensus_states/{client_id}";
}

// ClientParams queries all parameters of the ibc client.
rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) {
option (google.api.http).get = "/ibc/client/v1beta1/params";
}
}

// QueryClientStateRequest is the request type for the Query/ClientState RPC
Expand Down Expand Up @@ -65,7 +70,10 @@ message QueryClientStatesRequest {
// method.
message QueryClientStatesResponse {
// list of stored ClientStates of the chain.
repeated IdentifiedClientState client_states = 1;
repeated IdentifiedClientState client_states = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "IdentifiedClientStates"
];
// pagination response
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
Expand Down Expand Up @@ -113,3 +121,12 @@ message QueryConsensusStatesResponse {
// pagination response
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryClientParamsRequest is the request type for the Query/ClientParams RPC method.
message QueryClientParamsRequest {}

// QueryClientParamsResponse is the response type for the Query/ClientParams RPC method.
message QueryClientParamsResponse {
// params defines the parameters of the module.
Params params = 1;
}
93 changes: 93 additions & 0 deletions proto/ibc/core/client/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
syntax = "proto3";
package ibc.core.client.v1;

option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types";

import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "ibc/core/client/v1/client.proto";

// Msg defines the ibc/client Msg service.
service Msg {
// CreateClient defines a rpc handler method for MsgCreateClient.
rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse);

// UpdateClient defines a rpc handler method for MsgUpdateClient.
rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse);

// UpgradeClient defines a rpc handler method for MsgUpgradeClient.
rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse);

// SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour.
rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse);
}

// MsgCreateClient defines a message to create an IBC client
message MsgCreateClient {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// light client state
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
// consensus state associated with the client that corresponds to a given
// height.
google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
// signer address
string signer = 4;
}

// MsgCreateClientResponse defines the Msg/CreateClient response type.
message MsgCreateClientResponse { }

// MsgUpdateClient defines an sdk.Msg to update a IBC client state using
// the given header.
message MsgUpdateClient {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// header to update the light client
google.protobuf.Any header = 2;
// signer address
string signer = 3;
}

// MsgUpdateClientResponse defines the Msg/UpdateClient response type.
message MsgUpdateClientResponse { }

// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state
message MsgUpgradeClient {
// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// upgraded client state
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
// height at which old chain halts and upgrades (i.e last block executed)
Height upgrade_height = 3 [(gogoproto.moretags) = "yaml:\"upgrade_height\""];
// proof that old chain committed to new client
bytes proof_upgrade = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""];
// signer address
string signer = 5;
}

// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type.
message MsgUpgradeClientResponse { }

// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for
// light client misbehaviour.
message MsgSubmitMisbehaviour {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// misbehaviour used for freezing the light client
google.protobuf.Any misbehaviour = 2;
// signer address
string signer = 3;
}

// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response type.
message MsgSubmitMisbehaviourResponse { }
3 changes: 2 additions & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func NewSimApp(

// Create IBC Keeper
app.IBCKeeper = ibckeeper.NewKeeper(
appCodec, keys[ibchost.StoreKey], app.StakingKeeper, scopedIBCKeeper,
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, scopedIBCKeeper,
)

// register the proposal types
Expand Down Expand Up @@ -609,6 +609,7 @@ func initParamsKeeper(appCodec codec.BinaryMarshaler, legacyAmino *codec.LegacyA
paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable())
paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibchost.ModuleName)

return paramsKeeper
}
1 change: 1 addition & 0 deletions x/ibc/applications/transfer/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func GetQueryCmd() *cobra.Command {
queryCmd.AddCommand(
GetCmdQueryDenomTrace(),
GetCmdQueryDenomTraces(),
GetCmdParams(),
)

return queryCmd
Expand Down
4 changes: 2 additions & 2 deletions x/ibc/applications/transfer/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func GetCmdQueryDenomTraces() *cobra.Command {
return cmd
}

// QueryParamsCmd returns the command handler for ibc-transfer parameter querying.
func QueryParamsCmd() *cobra.Command {
// GetCmdParams returns the command handler for ibc-transfer parameter querying.
func GetCmdParams() *cobra.Command {
cmd := &cobra.Command{
Use: "params",
Short: "Query the current ibc-transfer parameters",
Expand Down
3 changes: 2 additions & 1 deletion x/ibc/applications/transfer/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
)

Expand All @@ -31,7 +32,7 @@ func (suite *TransferTestSuite) SetupTest() {
// constructs a send from chainA to chainB on the established channel/connection
// and sends the same coin back from chainB to chainA.
func (suite *TransferTestSuite) TestHandleMsgTransfer() {
clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB := suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
originalBalance := suite.chainA.App.BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
timeoutHeight := clienttypes.NewHeight(0, 110)
Expand Down
19 changes: 10 additions & 9 deletions x/ibc/applications/transfer/keeper/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
)

Expand All @@ -28,28 +29,28 @@ func (suite *KeeperTestSuite) TestSendTransfer() {
}{
{"successful transfer from source chain",
func() {
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
}, true, true},
{"successful transfer with coin from counterparty chain",
func() {
// send coin from chainA back to chainB
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
amount = types.GetTransferCoin(channelA.PortID, channelA.ID, sdk.DefaultBondDenom, 100)
}, false, true},
{"source channel not found",
func() {
// channel references wrong ID
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
channelA.ID = ibctesting.InvalidID
amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
}, true, false},
{"next seq send not found",
func() {
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA = connA.NextTestChannel(ibctesting.TransferPort)
channelB = connB.NextTestChannel(ibctesting.TransferPort)
// manually create channel so next seq send is never set
Expand All @@ -66,20 +67,20 @@ func (suite *KeeperTestSuite) TestSendTransfer() {
// - source chain
{"send coin failed",
func() {
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
amount = sdk.NewCoin("randomdenom", sdk.NewInt(100))
}, true, false},
// - receiving chain
{"send from module account failed",
func() {
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
amount = types.GetTransferCoin(channelA.PortID, channelA.ID, " randomdenom", 100)
}, false, false},
{"channel capability not found",
func() {
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
cap := suite.chainA.GetChannelCapability(channelA.PortID, channelA.ID)

Expand Down Expand Up @@ -177,7 +178,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
receiver = suite.chainB.SenderAccount.GetAddress().String() // must be explicitly changed in malleate

Expand Down Expand Up @@ -365,7 +366,7 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, ibctesting.Tendermint)
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB = suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
amount = sdk.NewInt(100) // must be explicitly changed
sender = suite.chainA.SenderAccount.GetAddress().String()
Expand Down
Loading

0 comments on commit 136f3ad

Please sign in to comment.