From 1c6e2679641d0892a3f35d778d7c2316a2937a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 1 Mar 2021 17:28:54 +0100 Subject: [PATCH] Remove IBC logic from x/upgrade (#8673) * add zeroed custom fields check to tm client * remove custom fields function from x/upgrade and fix tests * use []byte in x/upgrade, move abci to 02-client * remove x/ibc from types * whoops, delete testing files * fix upgrade tests * fix tm tests * fix tests * update CHANGELOG * revert proto breakage, use reserved field cc @amaurym * add IBC Upgrade Proposal type * remove IBC from upgrade types * add IBC upgrade logic to 02-client * fix all tests for x/upgrade * Add CLI for IBC Upgrade Proposal * Update x/ibc/core/02-client/types/proposal_test.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * add gRPC for upgraded client state * test fixes * add HandleUpgradeProposal tests * update docs and remove unnecessary code * self review bug and test fixes * neatness * construct empty rest handler * fix tests * fix stringer tests * Update docs/core/proto-docs.md Co-authored-by: Christopher Goes * add key in ibc store tracking ibc upgrade heights Add a new Key to the IBC client store to track the IBC Upgrade Height. This allows IBC upgrades to correctly remove old IBC upgrade states * update abci and tests * revert key storage after discussion with @AdityaSripal Revert using a key to track IBC upgrades. By clearing any IBC state using an old plan in ScheduleUpgrade, IBC upgrades do not need to be tracked by IBC. This reduces code complexity and reduces potential for bugs. * clear IBC states on cancelled upgrades Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Christopher Goes --- CHANGELOG.md | 1 + docs/core/proto-docs.md | 60 +- docs/ibc/upgrades/quick-guide.md | 8 +- proto/cosmos/bank/v1beta1/bank.proto | 2 +- proto/cosmos/upgrade/v1beta1/query.proto | 4 +- proto/cosmos/upgrade/v1beta1/upgrade.proto | 10 +- proto/ibc/core/client/v1/client.proto | 20 + proto/ibc/core/client/v1/query.proto | 22 + simapp/app.go | 6 +- x/gov/legacy/v040/migrate_test.go | 3 +- x/ibc/core/02-client/abci.go | 23 +- x/ibc/core/02-client/abci_test.go | 34 ++ x/ibc/core/02-client/client/cli/tx.go | 90 +++ .../core/02-client/client/proposal_handler.go | 19 +- x/ibc/core/02-client/keeper/client_test.go | 54 +- x/ibc/core/02-client/keeper/grpc_query.go | 43 ++ x/ibc/core/02-client/keeper/keeper.go | 19 +- x/ibc/core/02-client/keeper/proposal.go | 26 + x/ibc/core/02-client/keeper/proposal_test.go | 169 +++++- x/ibc/core/02-client/proposal_handler.go | 6 +- x/ibc/core/02-client/proposal_handler_test.go | 2 +- x/ibc/core/02-client/types/client.pb.go | 442 ++++++++++++-- x/ibc/core/02-client/types/codec.go | 1 + x/ibc/core/02-client/types/errors.go | 1 + .../core/02-client/types/expected_keepers.go | 11 + x/ibc/core/02-client/types/proposal.go | 94 ++- x/ibc/core/02-client/types/proposal_test.go | 150 ++++- x/ibc/core/02-client/types/query.pb.go | 541 ++++++++++++++++-- x/ibc/core/02-client/types/query.pb.gw.go | 116 ++++ x/ibc/core/keeper/grpc_query.go | 5 + x/ibc/core/keeper/keeper.go | 5 +- x/ibc/core/keeper/msg_server_test.go | 24 +- .../07-tendermint/types/upgrade.go | 4 +- .../07-tendermint/types/upgrade_test.go | 178 +++--- x/upgrade/abci.go | 16 - x/upgrade/abci_test.go | 89 +-- x/upgrade/keeper/grpc_query.go | 14 +- x/upgrade/keeper/keeper.go | 70 +-- x/upgrade/keeper/keeper_test.go | 99 +--- x/upgrade/types/plan.go | 34 +- x/upgrade/types/plan_test.go | 43 +- x/upgrade/types/proposal.go | 7 - x/upgrade/types/proposal_test.go | 19 +- x/upgrade/types/query.pb.go | 105 ++-- x/upgrade/types/upgrade.pb.go | 127 ++-- 45 files changed, 2019 insertions(+), 797 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cf3e8e366e8..dd5a0a56221b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/distribution) [\#8473](https://github.com/cosmos/cosmos-sdk/pull/8473) On genesis init, if the distribution module account balance, coming from bank module state, does not match the one in distribution module state, the initialization will panic. * (client/keys) [\#8500](https://github.com/cosmos/cosmos-sdk/pull/8500) `InfoImporter` interface is removed from legacy keybase. * [\#8629](https://github.com/cosmos/cosmos-sdk/pull/8629) Deprecated `SetFullFundraiserPath` from `Config` in favor of `SetPurpose` and `SetCoinType`. +* (x/upgrade) [\#8673](https://github.com/cosmos/cosmos-sdk/pull/8673) Remove IBC logic from x/upgrade. Deprecates IBC fields in an Upgrade Plan. IBC upgrade logic moved to 02-client and an IBC UpgradeProposal is added. ### State Machine Breaking diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 10e309d9e24a..9c1f7110adc6 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -567,6 +567,7 @@ - [Height](#ibc.core.client.v1.Height) - [IdentifiedClientState](#ibc.core.client.v1.IdentifiedClientState) - [Params](#ibc.core.client.v1.Params) + - [UpgradeProposal](#ibc.core.client.v1.UpgradeProposal) - [ibc/applications/transfer/v1/tx.proto](#ibc/applications/transfer/v1/tx.proto) - [MsgTransfer](#ibc.applications.transfer.v1.MsgTransfer) @@ -659,6 +660,8 @@ - [QueryConsensusStateResponse](#ibc.core.client.v1.QueryConsensusStateResponse) - [QueryConsensusStatesRequest](#ibc.core.client.v1.QueryConsensusStatesRequest) - [QueryConsensusStatesResponse](#ibc.core.client.v1.QueryConsensusStatesResponse) + - [QueryUpgradedClientStateRequest](#ibc.core.client.v1.QueryUpgradedClientStateRequest) + - [QueryUpgradedClientStateResponse](#ibc.core.client.v1.QueryUpgradedClientStateResponse) - [Query](#ibc.core.client.v1.Query) @@ -7509,7 +7512,6 @@ Plan specifies information about a planned upgrade and when it should occur. | `time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | The time after which the upgrade must be performed. Leave set to its zero value to use a pre-defined Height instead. | | `height` | [int64](#int64) | | The height at which the upgrade must be performed. Only used if Time is not set. | | `info` | [string](#string) | | Any application specific upgrade info to be included on-chain such as a git commit that validators could automatically upgrade to | -| `upgraded_client_state` | [google.protobuf.Any](#google.protobuf.Any) | | IBC-enabled chains can opt-in to including the upgraded client state in its upgrade plan This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the previous version of the chain. This will allow IBC connections to persist smoothly across planned chain upgrades | @@ -7634,7 +7636,7 @@ RPC method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `upgraded_consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | | +| `upgraded_consensus_state` | [bytes](#bytes) | | | @@ -8163,6 +8165,25 @@ Params defines the set of IBC light client parameters. + + + +### UpgradeProposal +UpgradeProposal is a gov Content type for initiating an IBC breaking +upgrade. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | | +| `description` | [string](#string) | | | +| `plan` | [cosmos.upgrade.v1beta1.Plan](#cosmos.upgrade.v1beta1.Plan) | | | +| `upgraded_client_state` | [google.protobuf.Any](#google.protobuf.Any) | | An UpgradedClientState must be provided to perform an IBC breaking upgrade. This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, so that connected chains can verify that the new upgraded client is valid by verifying a proof of the intended new client state on the previous version of the chain. This will allow IBC connections to persist smoothly across planned chain upgrades. | + + + + + @@ -9529,6 +9550,39 @@ Query/ConsensusStates RPC method + + + +### QueryUpgradedClientStateRequest +QueryUpgradedClientStateRequest is the request type for the Query/UpgradedClientState RPC +method + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `client_id` | [string](#string) | | client state unique identifier | +| `plan_height` | [int64](#int64) | | plan height of the current chain must be sent in request as this is the height under which upgraded client state is stored | + + + + + + + + +### QueryUpgradedClientStateResponse +QueryUpgradedClientStateResponse is the response type for the Query/UpgradedClientState RPC +method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `upgraded_client_state` | [google.protobuf.Any](#google.protobuf.Any) | | client state associated with the request identifier | + + + + + @@ -9548,6 +9602,7 @@ Query provides defines the gRPC querier service | `ConsensusState` | [QueryConsensusStateRequest](#ibc.core.client.v1.QueryConsensusStateRequest) | [QueryConsensusStateResponse](#ibc.core.client.v1.QueryConsensusStateResponse) | ConsensusState queries a consensus state associated with a client state at a given height. | GET|/ibc/core/client/v1beta1/consensus_states/{client_id}/revision/{revision_number}/height/{revision_height}| | `ConsensusStates` | [QueryConsensusStatesRequest](#ibc.core.client.v1.QueryConsensusStatesRequest) | [QueryConsensusStatesResponse](#ibc.core.client.v1.QueryConsensusStatesResponse) | ConsensusStates queries all the consensus state associated with a given client. | GET|/ibc/core/client/v1beta1/consensus_states/{client_id}| | `ClientParams` | [QueryClientParamsRequest](#ibc.core.client.v1.QueryClientParamsRequest) | [QueryClientParamsResponse](#ibc.core.client.v1.QueryClientParamsResponse) | ClientParams queries all parameters of the ibc client. | GET|/ibc/client/v1beta1/params| +| `UpgradedClientState` | [QueryUpgradedClientStateRequest](#ibc.core.client.v1.QueryUpgradedClientStateRequest) | [QueryUpgradedClientStateResponse](#ibc.core.client.v1.QueryUpgradedClientStateResponse) | UpgradedClientState queries an Upgraded IBC light client. | GET|/ibc/core/client/v1/upgraded_client_states/{client_id}| @@ -10840,4 +10895,3 @@ that implements Misbehaviour interface expected by ICS-02 | bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | | string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | | bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | - diff --git a/docs/ibc/upgrades/quick-guide.md b/docs/ibc/upgrades/quick-guide.md index 4717e52f44c1..d277de14faeb 100644 --- a/docs/ibc/upgrades/quick-guide.md +++ b/docs/ibc/upgrades/quick-guide.md @@ -30,10 +30,10 @@ Note: Since upgrades are only implemented for Tendermint clients, this doc only If the IBC-connected chain is conducting an upgrade that will break counterparty clients, it must ensure that the upgrade is first supported by IBC using the list above and then execute the upgrade process described below in order to prevent counterparty clients from breaking. -1. Create a `SoftwareUpgradeProposal` with an `UpgradePlan` that includes the new IBC ClientState in the `UpgradedClientState`. Note that the `UpgradePlan` must specify an upgrade height **only** (no upgrade time), and the `ClientState` should only include the fields common to all valid clients and zero out any client-customizable fields (such as TrustingPeriod). -2. Vote on and pass the `SoftwareUpgradeProposal` +1. Create an `UpgradeProposal` with an IBC ClientState in the `UpgradedClientState` field and a `UpgradePlan` in the `Plan` field. Note that the proposal `Plan` must specify an upgrade height **only** (no upgrade time), and the `ClientState` should only include the fields common to all valid clients and zero out any client-customizable fields (such as TrustingPeriod). +2. Vote on and pass the `UpgradeProposal` -Upon the `SoftwareUpgradeProposal` passing, the upgrade module will commit the UpgradedClient under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedClient`. On the block right before the upgrade height, the upgrade module will also commit an initial consensus state for the next chain under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedConsState`. +Upon the `UpgradeProposal` passing, the upgrade module will commit the UpgradedClient under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedClient`. On the block right before the upgrade height, the upgrade module will also commit an initial consensus state for the next chain under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedConsState`. Once the chain reaches the upgrade height and halts, a relayer can upgrade the counterparty clients to the last block of the old chain. They can then submit the proofs of the `UpgradedClient` and `UpgradedConsensusState` against this last block and upgrade the counterparty client. @@ -51,4 +51,4 @@ Thus, the upgrade process for relayers trying to upgrade the counterparty client The Tendermint client on the counterparty chain will verify that the upgrading chain did indeed commit to the upgraded client and upgraded consensus state at the upgrade height (since the upgrade height is included in the key). If the proofs are verified against the upgrade height, then the client will upgrade to the new client while retaining all of its client-customized fields. Thus, it will retain its old TrustingPeriod, TrustLevel, MaxClockDrift, etc; while adopting the new chain-specified fields such as UnbondingPeriod, ChainId, UpgradePath, etc. Note, this can lead to an invalid client since the old client-chosen fields may no longer be valid given the new chain-chosen fields. Upgrading chains should try to avoid these situations by not altering parameters that can break old clients. For an example, see the UnbondingPeriod example in the supported upgrades section. -The upgraded consensus state will serve purely as a basis of trust for future `UpdateClientMsgs` and will not contain a consensus root to perform proof verification against. Thus, relayers must submit an `UpdateClientMsg` with a header from the new chain so that the connection can be used for proof verification again. \ No newline at end of file +The upgraded consensus state will serve purely as a basis of trust for future `UpdateClientMsgs` and will not contain a consensus root to perform proof verification against. Thus, relayers must submit an `UpdateClientMsg` with a header from the new chain so that the connection can be used for proof verification again. diff --git a/proto/cosmos/bank/v1beta1/bank.proto b/proto/cosmos/bank/v1beta1/bank.proto index fb9069214415..b60027c88629 100644 --- a/proto/cosmos/bank/v1beta1/bank.proto +++ b/proto/cosmos/bank/v1beta1/bank.proto @@ -86,5 +86,5 @@ message Metadata { string name = 5; // symbol is the token symbol usually shown on exchanges (eg: ATOM). This can // be the same as the display. - string symbol = 6; + string symbol = 6; } diff --git a/proto/cosmos/upgrade/v1beta1/query.proto b/proto/cosmos/upgrade/v1beta1/query.proto index 9eab27e76b44..0fc6fd856f8d 100644 --- a/proto/cosmos/upgrade/v1beta1/query.proto +++ b/proto/cosmos/upgrade/v1beta1/query.proto @@ -64,5 +64,7 @@ message QueryUpgradedConsensusStateRequest { // QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState // RPC method. message QueryUpgradedConsensusStateResponse { - google.protobuf.Any upgraded_consensus_state = 1; + reserved 1; + + bytes upgraded_consensus_state = 2; } diff --git a/proto/cosmos/upgrade/v1beta1/upgrade.proto b/proto/cosmos/upgrade/v1beta1/upgrade.proto index 6d6839ca56c5..76fb14e2d3ca 100644 --- a/proto/cosmos/upgrade/v1beta1/upgrade.proto +++ b/proto/cosmos/upgrade/v1beta1/upgrade.proto @@ -34,12 +34,10 @@ message Plan { // such as a git commit that validators could automatically upgrade to string info = 4; - // IBC-enabled chains can opt-in to including the upgraded client state in its upgrade plan - // This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, - // so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the - // previous version of the chain. - // This will allow IBC connections to persist smoothly across planned chain upgrades - google.protobuf.Any upgraded_client_state = 5 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; + // UpgradedClientState field has been deprecated. IBC upgrade logic has been + // moved to the IBC module in the sub module 02-client. + reserved 5; + reserved "option"; } // SoftwareUpgradeProposal is a gov Content type for initiating a software diff --git a/proto/ibc/core/client/v1/client.proto b/proto/ibc/core/client/v1/client.proto index 4c6308bd5415..d8c0c28f498d 100644 --- a/proto/ibc/core/client/v1/client.proto +++ b/proto/ibc/core/client/v1/client.proto @@ -5,6 +5,7 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; // IdentifiedClientState defines a client state with an additional client // identifier field. @@ -52,6 +53,25 @@ message ClientUpdateProposal { Height initial_height = 5 [(gogoproto.moretags) = "yaml:\"initial_height\"", (gogoproto.nullable) = false]; } +// UpgradeProposal is a gov Content type for initiating an IBC breaking +// upgrade. +message UpgradeProposal { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; + cosmos.upgrade.v1beta1.Plan plan = 3 [(gogoproto.nullable) = false]; + + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, + // so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the + // previous version of the chain. + // This will allow IBC connections to persist smoothly across planned chain upgrades + google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} + // Height is a monotonically increasing data type // that can be compared against another Height for the purposes of updating and // freezing clients diff --git a/proto/ibc/core/client/v1/query.proto b/proto/ibc/core/client/v1/query.proto index 97f3acd62752..078571dd2b2f 100644 --- a/proto/ibc/core/client/v1/query.proto +++ b/proto/ibc/core/client/v1/query.proto @@ -38,6 +38,11 @@ service Query { rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { option (google.api.http).get = "/ibc/client/v1beta1/params"; } + + // UpgradedClientState queries an Upgraded IBC light client. + rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states/{client_id}"; + } } // QueryClientStateRequest is the request type for the Query/ClientState RPC @@ -128,3 +133,20 @@ message QueryClientParamsResponse { // params defines the parameters of the module. Params params = 1; } + +// QueryUpgradedClientStateRequest is the request type for the Query/UpgradedClientState RPC +// method +message QueryUpgradedClientStateRequest { + // client state unique identifier + string client_id = 1; + // plan height of the current chain must be sent in request + // as this is the height under which upgraded client state is stored + int64 plan_height = 2; +} + +// QueryUpgradedClientStateResponse is the response type for the Query/UpgradedClientState RPC +// method. +message QueryUpgradedClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any upgraded_client_state = 1; +} diff --git a/simapp/app.go b/simapp/app.go index 41376c8ee3a5..4086585e684c 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -69,6 +69,7 @@ import ( ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" ibc "github.com/cosmos/cosmos-sdk/x/ibc/core" ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client" + ibcclientclient "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/client" ibcclienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" porttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/05-port/types" ibchost "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" @@ -120,6 +121,7 @@ var ( distr.AppModuleBasic{}, gov.NewAppModuleBasic( paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, + ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, ), params.AppModuleBasic{}, crisis.AppModuleBasic{}, @@ -299,7 +301,7 @@ func NewSimApp( // Create IBC Keeper app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, scopedIBCKeeper, + appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, ) app.AuthzKeeper = authzkeeper.NewKeeper(keys[authztypes.StoreKey], appCodec, app.BaseApp.MsgServiceRouter()) @@ -310,7 +312,7 @@ func NewSimApp( AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). - AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) + AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) app.GovKeeper = govkeeper.NewKeeper( appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, &stakingKeeper, govRouter, diff --git a/x/gov/legacy/v040/migrate_test.go b/x/gov/legacy/v040/migrate_test.go index 049f5b885387..c28e43fdf2c9 100644 --- a/x/gov/legacy/v040/migrate_test.go +++ b/x/gov/legacy/v040/migrate_test.go @@ -176,8 +176,7 @@ func TestMigrate(t *testing.T) { "height": "123", "info": "foo_upgrade_info", "name": "foo_upgrade_name", - "time": "0001-01-01T00:00:00Z", - "upgraded_client_state": null + "time": "0001-01-01T00:00:00Z" }, "title": "foo_software_upgrade" }, diff --git a/x/ibc/core/02-client/abci.go b/x/ibc/core/02-client/abci.go index 3c56d90ad37a..163e513327b8 100644 --- a/x/ibc/core/02-client/abci.go +++ b/x/ibc/core/02-client/abci.go @@ -4,11 +4,32 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/keeper" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ) // BeginBlocker updates an existing localhost client with the latest block height. func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { - _, found := k.GetClientState(ctx, exported.Localhost) + plan, found := k.GetUpgradePlan(ctx) + if found { + // Once we are at the last block this chain will commit, set the upgraded consensus state + // so that IBC clients can use the last NextValidatorsHash as a trusted kernel for verifying + // headers on the next version of the chain. + // Set the time to the last block time of the current chain. + // In order for a client to upgrade successfully, the first block of the new chain must be committed + // within the trusting period of the last block time on this chain. + _, exists := k.GetUpgradedClient(ctx, plan.Height) + if exists && ctx.BlockHeight() == plan.Height-1 { + upgradedConsState := &ibctmtypes.ConsensusState{ + Timestamp: ctx.BlockTime(), + NextValidatorsHash: ctx.BlockHeader().NextValidatorsHash, + } + bz := k.MustMarshalConsensusState(upgradedConsState) + + k.SetUpgradedConsensusState(ctx, plan.Height, bz) + } + } + + _, found = k.GetClientState(ctx, exported.Localhost) if !found { return } diff --git a/x/ibc/core/02-client/abci_test.go b/x/ibc/core/02-client/abci_test.go index 3a296618b313..3f1f6ebdc289 100644 --- a/x/ibc/core/02-client/abci_test.go +++ b/x/ibc/core/02-client/abci_test.go @@ -4,12 +4,16 @@ import ( "testing" "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" client "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client" "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" localhosttypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/09-localhost/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) type ClientTestSuite struct { @@ -58,3 +62,33 @@ func (suite *ClientTestSuite) TestBeginBlocker() { prevHeight = localHostClient.GetLatestHeight().(types.Height) } } + +func (suite *ClientTestSuite) TestBeginBlockerConsensusState() { + plan := &upgradetypes.Plan{ + Name: "test", + Height: suite.chainA.GetContext().BlockHeight() + 1, + } + // set upgrade plan in the upgrade store + store := suite.chainA.GetContext().KVStore(suite.chainA.App.GetKey(upgradetypes.StoreKey)) + bz := suite.chainA.App.AppCodec().MustMarshalBinaryBare(plan) + store.Set(upgradetypes.PlanKey(), bz) + + nextValsHash := []byte("nextValsHash") + newCtx := suite.chainA.GetContext().WithBlockHeader(tmproto.Header{ + Height: suite.chainA.GetContext().BlockHeight(), + NextValidatorsHash: nextValsHash, + }) + + err := suite.chainA.App.UpgradeKeeper.SetUpgradedClient(newCtx, plan.Height, []byte("client state")) + suite.Require().NoError(err) + + req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} + suite.chainA.App.BeginBlock(req) + + // plan Height is at ctx.BlockHeight+1 + consState, found := suite.chainA.App.UpgradeKeeper.GetUpgradedConsensusState(newCtx, plan.Height) + suite.Require().True(found) + bz, err = types.MarshalConsensusState(suite.chainA.App.AppCodec(), &ibctmtypes.ConsensusState{Timestamp: newCtx.BlockTime(), NextValidatorsHash: nextValsHash}) + suite.Require().NoError(err) + suite.Require().Equal(bz, consState) +} diff --git a/x/ibc/core/02-client/client/cli/tx.go b/x/ibc/core/02-client/client/cli/tx.go index bdaa53a8ae1e..51c78bb4e737 100644 --- a/x/ibc/core/02-client/client/cli/tx.go +++ b/x/ibc/core/02-client/client/cli/tx.go @@ -18,6 +18,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // NewCreateClientCmd defines the command to create a new IBC light client. @@ -326,3 +327,92 @@ func NewCmdSubmitUpdateClientProposal() *cobra.Command { return cmd } + +// NewCmdSubmitUpgradeProposal implements a command handler for submitting an upgrade IBC client proposal transaction. +func NewCmdSubmitUpgradeProposal() *cobra.Command { + cmd := &cobra.Command{ + Use: "ibc-upgrade [name] [height] [path/to/upgraded_client_state.json] [flags]", + Args: cobra.ExactArgs(3), + Short: "Submit an IBC upgrade proposal", + Long: "Submit an IBC client breaking upgrade proposal along with an initial deposit.\n" + + "The client state specified is the upgraded client state representing the upgraded chain", + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) + + title, err := cmd.Flags().GetString(govcli.FlagTitle) + if err != nil { + return err + } + + description, err := cmd.Flags().GetString(govcli.FlagDescription) + if err != nil { + return err + } + + name := args[0] + + height, err := cmd.Flags().GetInt64(args[1]) + if err != nil { + return err + } + + plan := upgradetypes.Plan{ + Name: name, + Height: height, + } + + // attempt to unmarshal client state argument + var clientState exported.ClientState + clientContentOrFileName := args[2] + if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil { + + // check for file path if JSON input is not provided + contents, err := ioutil.ReadFile(clientContentOrFileName) + if err != nil { + return errors.Wrap(err, "neither JSON input nor path to .json file for client state were provided") + } + + if err := cdc.UnmarshalInterfaceJSON(contents, &clientState); err != nil { + return errors.Wrap(err, "error unmarshalling client state file") + } + } + + content, err := types.NewUpgradeProposal(title, description, plan, clientState) + if err != nil { + return err + } + + from := clientCtx.GetFromAddress() + + depositStr, err := cmd.Flags().GetString(govcli.FlagDeposit) + if err != nil { + return err + } + deposit, err := sdk.ParseCoinsNormalized(depositStr) + if err != nil { + return err + } + + msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) + if err != nil { + return err + } + + if err = msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(govcli.FlagTitle, "", "title of proposal") + cmd.Flags().String(govcli.FlagDescription, "", "description of proposal") + cmd.Flags().String(govcli.FlagDeposit, "", "deposit of proposal") + + return cmd +} diff --git a/x/ibc/core/02-client/client/proposal_handler.go b/x/ibc/core/02-client/client/proposal_handler.go index 63585cbe50b2..1f6f4065f0f1 100644 --- a/x/ibc/core/02-client/client/proposal_handler.go +++ b/x/ibc/core/02-client/client/proposal_handler.go @@ -1,8 +1,25 @@ package client import ( + "net/http" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/types/rest" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" + govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/client/cli" ) -var ProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpdateClientProposal, nil) +var ( + UpdateClientProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpdateClientProposal, emptyRestHandler) + UpgradeProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpgradeProposal, emptyRestHandler) +) + +func emptyRestHandler(client.Context) govrest.ProposalRESTHandler { + return govrest.ProposalRESTHandler{ + SubRoute: "unsupported-ibc-client", + Handler: func(w http.ResponseWriter, r *http.Request) { + rest.WriteErrorResponse(w, http.StatusBadRequest, "Legacy REST Routes are not supported for IBC proposals") + }, + } +} diff --git a/x/ibc/core/02-client/keeper/client_test.go b/x/ibc/core/02-client/keeper/client_test.go index 0cf5c1fe1d57..9eb816adf919 100644 --- a/x/ibc/core/02-client/keeper/client_test.go +++ b/x/ibc/core/02-client/keeper/client_test.go @@ -230,6 +230,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight exported.Height clientA string proofUpgradedClient, proofUpgradedConsState []byte + upgradedClientBz, upgradedConsStateBz []byte + err error ) testCases := []struct { @@ -240,18 +242,12 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { { name: "successful upgrade", setup: func() { - - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - upgradedConsState = &ibctmtypes.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // last Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -270,18 +266,12 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { { name: "client state not found", setup: func() { - - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - upgradedConsState = &ibctmtypes.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // last Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -302,18 +292,12 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { { name: "client state frozen", setup: func() { - - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - upgradedConsState = &ibctmtypes.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // last Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -338,18 +322,12 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { { name: "tendermint client VerifyUpgrade fails", setup: func() { - - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - upgradedConsState = &ibctmtypes.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // last Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // change upgradedClient client-specified parameters upgradedClient = ibctmtypes.NewClientState("wrongchainID", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, true, true) @@ -371,13 +349,23 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { for _, tc := range testCases { tc := tc clientA, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) + upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = upgradedClient.ZeroCustomFields() + upgradedClientBz, err = types.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) + + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + upgradedConsStateBz, err = types.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) + suite.Require().NoError(err) tc.setup() // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient upgradedClient = upgradedClient.ZeroCustomFields() - err := suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, upgradedConsState, proofUpgradedClient, proofUpgradedConsState) + err = suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, upgradedConsState, proofUpgradedClient, proofUpgradedConsState) if tc.expPass { suite.Require().NoError(err, "verify upgrade failed on valid case: %s", tc.name) diff --git a/x/ibc/core/02-client/keeper/grpc_query.go b/x/ibc/core/02-client/keeper/grpc_query.go index 2134427729ae..cc4b256d30e7 100644 --- a/x/ibc/core/02-client/keeper/grpc_query.go +++ b/x/ibc/core/02-client/keeper/grpc_query.go @@ -197,3 +197,46 @@ func (q Keeper) ClientParams(c context.Context, _ *types.QueryClientParamsReques Params: ¶ms, }, nil } + +// UpgradedClientState implements the Query/UpgradedClientState gRPC method +func (q Keeper) UpgradedClientState(c context.Context, req *types.QueryUpgradedClientStateRequest) (*types.QueryUpgradedClientStateResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + if err := host.ClientIdentifierValidator(req.ClientId); err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + ctx := sdk.UnwrapSDKContext(c) + plan, found := q.GetUpgradePlan(ctx) + if !found { + return nil, status.Error( + codes.NotFound, "upgrade plan not found", + ) + } + + bz, found := q.GetUpgradedClient(ctx, plan.Height) + if !found { + return nil, status.Error( + codes.NotFound, + sdkerrors.Wrap(types.ErrClientNotFound, req.ClientId).Error(), + ) + } + + clientState, err := types.UnmarshalClientState(q.cdc, bz) + if err != nil { + return nil, status.Error( + codes.Internal, err.Error(), + ) + } + + any, err := types.PackClientState(clientState) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryUpgradedClientStateResponse{ + UpgradedClientState: any, + }, nil +} diff --git a/x/ibc/core/02-client/keeper/keeper.go b/x/ibc/core/02-client/keeper/keeper.go index 67c5c0658d40..43ac1feb3523 100644 --- a/x/ibc/core/02-client/keeper/keeper.go +++ b/x/ibc/core/02-client/keeper/keeper.go @@ -28,10 +28,11 @@ type Keeper struct { cdc codec.BinaryMarshaler paramSpace paramtypes.Subspace stakingKeeper types.StakingKeeper + upgradeKeeper types.UpgradeKeeper } // NewKeeper creates a new NewKeeper instance -func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey, paramSpace paramtypes.Subspace, sk types.StakingKeeper) Keeper { +func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey, paramSpace paramtypes.Subspace, sk types.StakingKeeper, uk types.UpgradeKeeper) Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) @@ -42,6 +43,7 @@ func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey, paramSpace paramtype cdc: cdc, paramSpace: paramSpace, stakingKeeper: sk, + upgradeKeeper: uk, } } @@ -327,6 +329,21 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS return nil } +// GetUpgradePlan executes the upgrade keeper GetUpgradePlan function. +func (k Keeper) GetUpgradePlan(ctx sdk.Context) (plan upgradetypes.Plan, havePlan bool) { + return k.upgradeKeeper.GetUpgradePlan(ctx) +} + +// GetUpgradedClient executes the upgrade keeper GetUpgradeClient function. +func (k Keeper) GetUpgradedClient(ctx sdk.Context, planHeight int64) ([]byte, bool) { + return k.upgradeKeeper.GetUpgradedClient(ctx, planHeight) +} + +// SetUpgradedConsensusState executes the upgrade keeper SetUpgradedConsensusState function. +func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, bz []byte) error { + return k.upgradeKeeper.SetUpgradedConsensusState(ctx, planHeight, bz) +} + // IterateClients provides an iterator over all stored light client State // objects. For each State object, cb will be called. If the cb returns true, // the iterator will close and stop. diff --git a/x/ibc/core/02-client/keeper/proposal.go b/x/ibc/core/02-client/keeper/proposal.go index 6d4ff350df32..812df5e138de 100644 --- a/x/ibc/core/02-client/keeper/proposal.go +++ b/x/ibc/core/02-client/keeper/proposal.go @@ -70,3 +70,29 @@ func (k Keeper) ClientUpdateProposal(ctx sdk.Context, p *types.ClientUpdatePropo return nil } + +// HandleUpgradeProposal sets the upgraded client state in the upgrade store. It clears +// an IBC client state and consensus state if a previous plan was set. Then it +// will schedule an upgrade and finally set the upgraded client state in upgrade +// store. +func (k Keeper) HandleUpgradeProposal(ctx sdk.Context, p *types.UpgradeProposal) error { + clientState, err := types.UnpackClientState(p.UpgradedClientState) + if err != nil { + return sdkerrors.Wrap(err, "could not unpack UpgradedClientState") + } + + // zero out any custom fields before setting + cs := clientState.ZeroCustomFields() + bz, err := types.MarshalClientState(k.cdc, cs) + if err != nil { + return sdkerrors.Wrap(err, "could not marshal UpgradedClientState") + } + + if err := k.upgradeKeeper.ScheduleUpgrade(ctx, p.Plan); err != nil { + return err + } + + // sets the new upgraded client in last height committed on this chain is at plan.Height, + // since the chain will panic at plan.Height and new chain will resume at plan.Height + return k.upgradeKeeper.SetUpgradedClient(ctx, p.Plan.Height, bz) +} diff --git a/x/ibc/core/02-client/keeper/proposal_test.go b/x/ibc/core/02-client/keeper/proposal_test.go index 8dbe43f7d7f7..82d7e120dbcf 100644 --- a/x/ibc/core/02-client/keeper/proposal_test.go +++ b/x/ibc/core/02-client/keeper/proposal_test.go @@ -1,19 +1,20 @@ package keeper_test import ( + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) func (suite *KeeperTestSuite) TestClientUpdateProposal() { var ( subject, substitute string subjectClientState, substituteClientState exported.ClientState - initialHeight clienttypes.Height - content *types.ClientUpdateProposal + initialHeight types.Height + content govtypes.Content err error ) @@ -24,7 +25,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { }{ { "valid update client proposal", func() { - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) }, true, }, { @@ -35,52 +36,52 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { suite.Require().True(found) newRevisionNumber := tmClientState.GetLatestHeight().GetRevisionNumber() + 1 - tmClientState.LatestHeight = clienttypes.NewHeight(newRevisionNumber, tmClientState.GetLatestHeight().GetRevisionHeight()) - initialHeight = clienttypes.NewHeight(newRevisionNumber, initialHeight.GetRevisionHeight()) + tmClientState.LatestHeight = types.NewHeight(newRevisionNumber, tmClientState.GetLatestHeight().GetRevisionHeight()) + initialHeight = types.NewHeight(newRevisionNumber, initialHeight.GetRevisionHeight()) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), substitute, tmClientState.LatestHeight, consState) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, tmClientState) - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) }, true, }, { "cannot use localhost as subject", func() { - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, exported.Localhost, substitute, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, exported.Localhost, substitute, initialHeight) }, false, }, { "cannot use localhost as substitute", func() { - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, exported.Localhost, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, exported.Localhost, initialHeight) }, false, }, { "subject client does not exist", func() { - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, ibctesting.InvalidID, substitute, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, ibctesting.InvalidID, substitute, initialHeight) }, false, }, { "substitute client does not exist", func() { - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, ibctesting.InvalidID, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, ibctesting.InvalidID, initialHeight) }, false, }, { "subject and substitute have equal latest height", func() { tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState) suite.Require().True(ok) - tmClientState.LatestHeight = substituteClientState.GetLatestHeight().(clienttypes.Height) + tmClientState.LatestHeight = substituteClientState.GetLatestHeight().(types.Height) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) }, false, }, { "update fails, client is not frozen or expired", func() { tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState) suite.Require().True(ok) - tmClientState.FrozenHeight = clienttypes.ZeroHeight() + tmClientState.FrozenHeight = types.ZeroHeight() suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) - content = clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) + content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute, initialHeight) }, false, }, } @@ -94,7 +95,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { subject, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) subjectClientState = suite.chainA.GetClientState(subject) substitute, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - initialHeight = clienttypes.NewHeight(subjectClientState.GetLatestHeight().GetRevisionNumber(), subjectClientState.GetLatestHeight().GetRevisionHeight()+1) + initialHeight = types.NewHeight(subjectClientState.GetLatestHeight().GetRevisionNumber(), subjectClientState.GetLatestHeight().GetRevisionHeight()+1) // update substitute twice suite.coordinator.UpdateClient(suite.chainA, suite.chainB, substitute, exported.Tendermint) @@ -117,7 +118,9 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { tc.malleate() - err = suite.chainA.App.IBCKeeper.ClientKeeper.ClientUpdateProposal(suite.chainA.GetContext(), content) + updateProp, ok := content.(*types.ClientUpdateProposal) + suite.Require().True(ok) + err = suite.chainA.App.IBCKeeper.ClientKeeper.ClientUpdateProposal(suite.chainA.GetContext(), updateProp) if tc.expPass { suite.Require().NoError(err) @@ -128,3 +131,135 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { } } + +func (suite *KeeperTestSuite) TestHandleUpgradeProposal() { + var ( + upgradedClientState *ibctmtypes.ClientState + oldPlan, plan upgradetypes.Plan + content govtypes.Content + err error + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "valid upgrade proposal", func() { + content, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, upgradedClientState) + suite.Require().NoError(err) + }, true, + }, + { + "valid upgrade proposal with previous IBC state", func() { + oldPlan = upgradetypes.Plan{ + Name: "upgrade IBC clients", + Height: 100, + } + + content, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, upgradedClientState) + suite.Require().NoError(err) + }, true, + }, + { + "cannot unpack client state", func() { + any, err := types.PackConsensusState(&ibctmtypes.ConsensusState{}) + suite.Require().NoError(err) + content = &types.UpgradeProposal{ + Title: ibctesting.Title, + Description: ibctesting.Description, + Plan: plan, + UpgradedClientState: any, + } + }, false, + }, + { + "schedule upgrade fails - plan sets time and height", func() { + plan = upgradetypes.Plan{ + Name: "invalid plan", + Height: 1000, + Time: suite.chainA.GetContext().BlockTime(), + } + content, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, upgradedClientState) + suite.Require().NoError(err) + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + oldPlan.Height = 0 //reset + + clientID, _ := suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) + upgradedClientState = suite.chainA.GetClientState(clientID).ZeroCustomFields().(*ibctmtypes.ClientState) + + // use height 1000 to distinguish from old plan + plan = upgradetypes.Plan{ + Name: "upgrade IBC clients", + Height: 1000, + } + + tc.malleate() + + // set the old plan if it is not empty + if oldPlan.Height != 0 { + // set upgrade plan in the upgrade store + store := suite.chainA.GetContext().KVStore(suite.chainA.App.GetKey(upgradetypes.StoreKey)) + bz := suite.chainA.App.AppCodec().MustMarshalBinaryBare(&oldPlan) + store.Set(upgradetypes.PlanKey(), bz) + + bz, err := types.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClientState) + suite.Require().NoError(err) + suite.chainA.App.UpgradeKeeper.SetUpgradedClient(suite.chainA.GetContext(), oldPlan.Height, bz) + } + + upgradeProp, ok := content.(*types.UpgradeProposal) + suite.Require().True(ok) + err = suite.chainA.App.IBCKeeper.ClientKeeper.HandleUpgradeProposal(suite.chainA.GetContext(), upgradeProp) + + if tc.expPass { + suite.Require().NoError(err) + + // check that the correct plan is returned + storedPlan, found := suite.chainA.App.UpgradeKeeper.GetUpgradePlan(suite.chainA.GetContext()) + suite.Require().True(found) + suite.Require().Equal(plan, storedPlan) + + // check that old upgraded client state is cleared + _, found = suite.chainA.App.UpgradeKeeper.GetUpgradedClient(suite.chainA.GetContext(), oldPlan.Height) + suite.Require().False(found) + + // check that client state was set + storedClientState, found := suite.chainA.App.UpgradeKeeper.GetUpgradedClient(suite.chainA.GetContext(), plan.Height) + suite.Require().True(found) + clientState, err := types.UnmarshalClientState(suite.chainA.App.AppCodec(), storedClientState) + suite.Require().NoError(err) + suite.Require().Equal(upgradedClientState, clientState) + } else { + suite.Require().Error(err) + + // check that the new plan wasn't stored + storedPlan, found := suite.chainA.App.UpgradeKeeper.GetUpgradePlan(suite.chainA.GetContext()) + if oldPlan.Height != 0 { + // NOTE: this is only true if the ScheduleUpgrade function + // returns an error before clearing the old plan + suite.Require().True(found) + suite.Require().Equal(oldPlan, storedPlan) + } else { + suite.Require().False(found) + suite.Require().Empty(storedPlan) + } + + // check that client state was not set + _, found = suite.chainA.App.UpgradeKeeper.GetUpgradedClient(suite.chainA.GetContext(), plan.Height) + suite.Require().False(found) + + } + }) + } + +} diff --git a/x/ibc/core/02-client/proposal_handler.go b/x/ibc/core/02-client/proposal_handler.go index befa95df642f..f035ca99a0cc 100644 --- a/x/ibc/core/02-client/proposal_handler.go +++ b/x/ibc/core/02-client/proposal_handler.go @@ -8,12 +8,14 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" ) -// NewClientUpdateProposalHandler defines the client update proposal handler -func NewClientUpdateProposalHandler(k keeper.Keeper) govtypes.Handler { +// NewClientProposalHandler defines the 02-client proposal handler +func NewClientProposalHandler(k keeper.Keeper) govtypes.Handler { return func(ctx sdk.Context, content govtypes.Content) error { switch c := content.(type) { case *types.ClientUpdateProposal: return k.ClientUpdateProposal(ctx, c) + case *types.UpgradeProposal: + return k.HandleUpgradeProposal(ctx, c) default: return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ibc proposal content type: %T", c) diff --git a/x/ibc/core/02-client/proposal_handler_test.go b/x/ibc/core/02-client/proposal_handler_test.go index 41b893186d65..502da898e8a6 100644 --- a/x/ibc/core/02-client/proposal_handler_test.go +++ b/x/ibc/core/02-client/proposal_handler_test.go @@ -69,7 +69,7 @@ func (suite *ClientTestSuite) TestNewClientUpdateProposalHandler() { tc.malleate() - proposalHandler := client.NewClientUpdateProposalHandler(suite.chainA.App.IBCKeeper.ClientKeeper) + proposalHandler := client.NewClientProposalHandler(suite.chainA.App.IBCKeeper.ClientKeeper) err = proposalHandler(suite.chainA.GetContext(), content) diff --git a/x/ibc/core/02-client/types/client.pb.go b/x/ibc/core/02-client/types/client.pb.go index 61bdd9bf804d..a9a799453900 100644 --- a/x/ibc/core/02-client/types/client.pb.go +++ b/x/ibc/core/02-client/types/client.pb.go @@ -6,6 +6,7 @@ package types import ( fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" + types1 "github.com/cosmos/cosmos-sdk/x/upgrade/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" @@ -242,6 +243,52 @@ func (m *ClientUpdateProposal) XXX_DiscardUnknown() { var xxx_messageInfo_ClientUpdateProposal proto.InternalMessageInfo +// UpgradeProposal is a gov Content type for initiating an IBC breaking +// upgrade. +type UpgradeProposal struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Plan types1.Plan `protobuf:"bytes,3,opt,name=plan,proto3" json:"plan"` + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, + // so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the + // previous version of the chain. + // This will allow IBC connections to persist smoothly across planned chain upgrades + UpgradedClientState *types.Any `protobuf:"bytes,4,opt,name=upgraded_client_state,json=upgradedClientState,proto3" json:"upgraded_client_state,omitempty" yaml:"upgraded_client_state"` +} + +func (m *UpgradeProposal) Reset() { *m = UpgradeProposal{} } +func (*UpgradeProposal) ProtoMessage() {} +func (*UpgradeProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_b6bc4c8185546947, []int{4} +} +func (m *UpgradeProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UpgradeProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UpgradeProposal.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UpgradeProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpgradeProposal.Merge(m, src) +} +func (m *UpgradeProposal) XXX_Size() int { + return m.Size() +} +func (m *UpgradeProposal) XXX_DiscardUnknown() { + xxx_messageInfo_UpgradeProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_UpgradeProposal proto.InternalMessageInfo + // Height is a monotonically increasing data type // that can be compared against another Height for the purposes of updating and // freezing clients @@ -261,7 +308,7 @@ type Height struct { func (m *Height) Reset() { *m = Height{} } func (*Height) ProtoMessage() {} func (*Height) Descriptor() ([]byte, []int) { - return fileDescriptor_b6bc4c8185546947, []int{4} + return fileDescriptor_b6bc4c8185546947, []int{5} } func (m *Height) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -300,7 +347,7 @@ func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_b6bc4c8185546947, []int{5} + return fileDescriptor_b6bc4c8185546947, []int{6} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -341,6 +388,7 @@ func init() { proto.RegisterType((*ConsensusStateWithHeight)(nil), "ibc.core.client.v1.ConsensusStateWithHeight") proto.RegisterType((*ClientConsensusStates)(nil), "ibc.core.client.v1.ClientConsensusStates") proto.RegisterType((*ClientUpdateProposal)(nil), "ibc.core.client.v1.ClientUpdateProposal") + proto.RegisterType((*UpgradeProposal)(nil), "ibc.core.client.v1.UpgradeProposal") proto.RegisterType((*Height)(nil), "ibc.core.client.v1.Height") proto.RegisterType((*Params)(nil), "ibc.core.client.v1.Params") } @@ -348,50 +396,89 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/client.proto", fileDescriptor_b6bc4c8185546947) } var fileDescriptor_b6bc4c8185546947 = []byte{ - // 641 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xbf, 0x6e, 0xd3, 0x40, - 0x1c, 0x8e, 0xd3, 0x34, 0x6a, 0x2e, 0x90, 0x14, 0x93, 0xd0, 0x34, 0x40, 0x2e, 0xba, 0x29, 0x03, - 0xb5, 0x69, 0x18, 0x40, 0xdd, 0x48, 0x96, 0x76, 0x00, 0xb5, 0x87, 0x10, 0x88, 0x25, 0xf8, 0xcf, - 0x35, 0x39, 0x70, 0x7c, 0x91, 0xef, 0x5c, 0x9a, 0x37, 0x60, 0x64, 0x64, 0x60, 0xe0, 0x09, 0x78, - 0x0a, 0x86, 0x8e, 0x95, 0x58, 0x98, 0x2c, 0xd4, 0xbe, 0x81, 0x9f, 0x00, 0xf9, 0xee, 0x92, 0x36, - 0x29, 0x15, 0x88, 0xc9, 0x3f, 0x7f, 0xf7, 0xfd, 0xbe, 0xdf, 0xf7, 0xfb, 0x74, 0x36, 0x80, 0xd4, - 0xf5, 0x6c, 0x8f, 0x45, 0xc4, 0xf6, 0x02, 0x4a, 0x42, 0x61, 0x1f, 0x6d, 0xeb, 0xca, 0x9a, 0x44, - 0x4c, 0x30, 0xd3, 0xa4, 0xae, 0x67, 0x65, 0x04, 0x4b, 0xc3, 0x47, 0xdb, 0xcd, 0xda, 0x90, 0x0d, - 0x99, 0x3c, 0xb6, 0xb3, 0x4a, 0x31, 0x9b, 0x9b, 0x43, 0xc6, 0x86, 0x01, 0xb1, 0xe5, 0x9b, 0x1b, - 0x1f, 0xda, 0x4e, 0x38, 0x55, 0x47, 0xe8, 0x8b, 0x01, 0xea, 0x7b, 0x3e, 0x09, 0x05, 0x3d, 0xa4, - 0xc4, 0xef, 0x4b, 0xa1, 0x17, 0xc2, 0x11, 0xc4, 0xdc, 0x06, 0x25, 0xa5, 0x3b, 0xa0, 0x7e, 0xc3, - 0x68, 0x1b, 0x9d, 0x52, 0xaf, 0x96, 0x26, 0x70, 0x7d, 0xea, 0x8c, 0x83, 0x1d, 0x34, 0x3f, 0x42, - 0x78, 0x4d, 0xd5, 0x7b, 0xbe, 0xb9, 0x0f, 0x6e, 0x68, 0x9c, 0x67, 0x12, 0x8d, 0x7c, 0xdb, 0xe8, - 0x94, 0xbb, 0x35, 0x4b, 0x8d, 0xb7, 0x66, 0xe3, 0xad, 0xa7, 0xe1, 0xb4, 0xb7, 0x91, 0x26, 0xf0, - 0xf6, 0x82, 0x96, 0xec, 0x41, 0xb8, 0xec, 0x5d, 0x98, 0x40, 0xdf, 0x0c, 0xd0, 0xe8, 0xb3, 0x90, - 0x93, 0x90, 0xc7, 0x5c, 0x42, 0xaf, 0xa8, 0x18, 0xed, 0x12, 0x3a, 0x1c, 0x09, 0xf3, 0x09, 0x28, - 0x8e, 0x64, 0x25, 0xed, 0x95, 0xbb, 0x4d, 0xeb, 0x6a, 0x22, 0x96, 0xe2, 0xf6, 0x0a, 0x27, 0x09, - 0xcc, 0x61, 0xcd, 0x37, 0x5f, 0x83, 0xaa, 0x37, 0x53, 0xfd, 0x07, 0xaf, 0x9b, 0x69, 0x02, 0xeb, - 0x99, 0x57, 0xb4, 0xd4, 0x85, 0x70, 0xc5, 0x5b, 0x70, 0x87, 0xbe, 0x1b, 0xa0, 0xae, 0x52, 0x5c, - 0xb4, 0xcd, 0xff, 0x27, 0xcf, 0x63, 0xb0, 0xbe, 0x34, 0x90, 0x37, 0xf2, 0xed, 0x95, 0x4e, 0xb9, - 0xfb, 0xe0, 0x4f, 0xab, 0x5e, 0x17, 0x54, 0x0f, 0x66, 0xcb, 0xa7, 0x09, 0xdc, 0xd0, 0xb3, 0x96, - 0x34, 0x11, 0xae, 0x2e, 0x6e, 0xc1, 0xd1, 0x8f, 0x3c, 0xa8, 0xa9, 0x35, 0x5e, 0x4e, 0x7c, 0x47, - 0x90, 0xfd, 0x88, 0x4d, 0x18, 0x77, 0x02, 0xb3, 0x06, 0x56, 0x05, 0x15, 0x01, 0x51, 0x1b, 0x60, - 0xf5, 0x62, 0xb6, 0x41, 0xd9, 0x27, 0xdc, 0x8b, 0xe8, 0x44, 0x50, 0x16, 0xca, 0x2c, 0x4b, 0xf8, - 0x32, 0x64, 0xee, 0x82, 0x5b, 0x3c, 0x76, 0xdf, 0x11, 0x4f, 0x0c, 0x2e, 0x52, 0x58, 0x91, 0x29, - 0xdc, 0x4b, 0x13, 0xd8, 0x50, 0xce, 0xae, 0x50, 0x10, 0xae, 0x6a, 0xac, 0x3f, 0x0b, 0xe5, 0x00, - 0xd4, 0x78, 0xec, 0x72, 0x41, 0x45, 0x2c, 0xc8, 0x25, 0xb1, 0x82, 0x14, 0x83, 0x69, 0x02, 0xef, - 0xce, 0xc4, 0xb8, 0xbb, 0xcc, 0x42, 0xd8, 0xbc, 0x68, 0x9e, 0x4b, 0xbe, 0x05, 0x15, 0x1a, 0x52, - 0x41, 0x9d, 0x60, 0xa0, 0x2f, 0xd4, 0xea, 0x5f, 0x2f, 0xd4, 0x7d, 0x9d, 0x69, 0x5d, 0x0d, 0x5b, - 0xec, 0x47, 0xf8, 0xa6, 0x06, 0x14, 0x7b, 0xa7, 0xf0, 0xf1, 0x2b, 0xcc, 0x65, 0x1f, 0x5b, 0x51, - 0xdf, 0xdd, 0x3e, 0xa8, 0x46, 0xe4, 0x88, 0x72, 0xca, 0xc2, 0x41, 0x18, 0x8f, 0x5d, 0x12, 0xc9, - 0x44, 0x0b, 0xbd, 0x66, 0x9a, 0xc0, 0x3b, 0x4a, 0x73, 0x89, 0x80, 0x70, 0x65, 0x86, 0x3c, 0x97, - 0xc0, 0x82, 0x88, 0x36, 0x9e, 0xbf, 0x56, 0x64, 0xe6, 0x6c, 0x2e, 0xa2, 0xad, 0xad, 0x65, 0xd6, - 0x3e, 0x67, 0xf6, 0x9e, 0x81, 0xe2, 0xbe, 0x13, 0x39, 0x63, 0x9e, 0x09, 0x3b, 0x41, 0xc0, 0x3e, - 0x10, 0x5f, 0x47, 0xc7, 0x1b, 0x46, 0x7b, 0xa5, 0x53, 0xba, 0x2c, 0xbc, 0x44, 0x40, 0xb8, 0xa2, - 0x11, 0x15, 0x2b, 0xef, 0x1d, 0x9c, 0x9c, 0xb5, 0x8c, 0xd3, 0xb3, 0x96, 0xf1, 0xeb, 0xac, 0x65, - 0x7c, 0x3a, 0x6f, 0xe5, 0x4e, 0xcf, 0x5b, 0xb9, 0x9f, 0xe7, 0xad, 0xdc, 0x9b, 0xc7, 0x43, 0x2a, - 0x46, 0xb1, 0x6b, 0x79, 0x6c, 0x6c, 0x7b, 0x8c, 0x8f, 0x19, 0xd7, 0x8f, 0x2d, 0xee, 0xbf, 0xb7, - 0x8f, 0xed, 0xf9, 0x9f, 0xef, 0x61, 0x77, 0x4b, 0xff, 0xfc, 0xc4, 0x74, 0x42, 0xb8, 0x5b, 0x94, - 0x9f, 0xe5, 0xa3, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x95, 0xe2, 0x8e, 0x47, 0x1c, 0x05, 0x00, - 0x00, + // 740 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x3f, 0x6f, 0xd3, 0x4e, + 0x18, 0x8e, 0xd3, 0x34, 0x6a, 0x2e, 0xfd, 0x25, 0xfd, 0xb9, 0x09, 0x4d, 0x43, 0x89, 0xa3, 0x13, + 0x43, 0x06, 0x6a, 0x93, 0x20, 0x01, 0xea, 0x46, 0xb2, 0xb4, 0x03, 0x28, 0x35, 0xaa, 0x40, 0x2c, + 0xc1, 0x7f, 0xae, 0xc9, 0x15, 0xc7, 0x17, 0xf9, 0xce, 0xa1, 0xf9, 0x06, 0x8c, 0x8c, 0x0c, 0x0c, + 0xfd, 0x04, 0x7c, 0x0a, 0x86, 0x8e, 0x95, 0x58, 0x98, 0x2c, 0xd4, 0x2e, 0xcc, 0x5e, 0x59, 0x90, + 0x7d, 0xe7, 0x34, 0x49, 0x5b, 0x40, 0x30, 0xf9, 0xee, 0xbd, 0xe7, 0x9e, 0xf7, 0x7d, 0x9e, 0xbb, + 0xf7, 0x0c, 0x14, 0x6c, 0x5a, 0x9a, 0x45, 0x3c, 0xa4, 0x59, 0x0e, 0x46, 0x2e, 0xd3, 0xc6, 0x4d, + 0x31, 0x52, 0x47, 0x1e, 0x61, 0x44, 0x96, 0xb1, 0x69, 0xa9, 0x11, 0x40, 0x15, 0xe1, 0x71, 0xb3, + 0x5a, 0xea, 0x93, 0x3e, 0x89, 0x97, 0xb5, 0x68, 0xc4, 0x91, 0xd5, 0xcd, 0x3e, 0x21, 0x7d, 0x07, + 0x69, 0xf1, 0xcc, 0xf4, 0x0f, 0x35, 0xc3, 0x9d, 0x88, 0xa5, 0xbb, 0x16, 0xa1, 0x43, 0x42, 0x35, + 0x7f, 0xd4, 0xf7, 0x0c, 0x1b, 0x69, 0xe3, 0xa6, 0x89, 0x98, 0xd1, 0x4c, 0xe6, 0x1c, 0x05, 0x3f, + 0x4a, 0xa0, 0xbc, 0x67, 0x23, 0x97, 0xe1, 0x43, 0x8c, 0xec, 0x4e, 0x9c, 0xee, 0x39, 0x33, 0x18, + 0x92, 0x9b, 0x20, 0xc7, 0xb3, 0xf7, 0xb0, 0x5d, 0x91, 0xea, 0x52, 0x23, 0xd7, 0x2e, 0x85, 0x81, + 0xb2, 0x36, 0x31, 0x86, 0xce, 0x0e, 0x9c, 0x2e, 0x41, 0x7d, 0x85, 0x8f, 0xf7, 0x6c, 0xb9, 0x0b, + 0x56, 0x45, 0x9c, 0x46, 0x14, 0x95, 0x74, 0x5d, 0x6a, 0xe4, 0x5b, 0x25, 0x95, 0x17, 0xa9, 0x26, + 0x45, 0xaa, 0x4f, 0xdc, 0x49, 0x7b, 0x23, 0x0c, 0x94, 0xf5, 0x39, 0xae, 0x78, 0x0f, 0xd4, 0xf3, + 0xd6, 0x65, 0x11, 0xf0, 0x93, 0x04, 0x2a, 0x1d, 0xe2, 0x52, 0xe4, 0x52, 0x9f, 0xc6, 0xa1, 0x17, + 0x98, 0x0d, 0x76, 0x11, 0xee, 0x0f, 0x98, 0xfc, 0x18, 0x64, 0x07, 0xf1, 0x28, 0x2e, 0x2f, 0xdf, + 0xaa, 0xaa, 0x57, 0x7d, 0x53, 0x39, 0xb6, 0x9d, 0x39, 0x0d, 0x94, 0x94, 0x2e, 0xf0, 0xf2, 0x4b, + 0x50, 0xb4, 0x12, 0xd6, 0x3f, 0xa8, 0x75, 0x33, 0x0c, 0x94, 0x72, 0x54, 0x2b, 0x5c, 0xd8, 0x05, + 0xf5, 0x82, 0x35, 0x57, 0x1d, 0xfc, 0x2c, 0x81, 0x32, 0x77, 0x71, 0xbe, 0x6c, 0xfa, 0x37, 0x7e, + 0x1e, 0x83, 0xb5, 0x85, 0x84, 0xb4, 0x92, 0xae, 0x2f, 0x35, 0xf2, 0xad, 0x7b, 0xd7, 0x49, 0xbd, + 0xc9, 0xa8, 0xb6, 0x12, 0x89, 0x0f, 0x03, 0x65, 0x43, 0xe4, 0x5a, 0xe0, 0x84, 0x7a, 0x71, 0x5e, + 0x05, 0x85, 0x5f, 0xd2, 0xa0, 0xc4, 0x65, 0x1c, 0x8c, 0x6c, 0x83, 0xa1, 0xae, 0x47, 0x46, 0x84, + 0x1a, 0x8e, 0x5c, 0x02, 0xcb, 0x0c, 0x33, 0x07, 0x71, 0x05, 0x3a, 0x9f, 0xc8, 0x75, 0x90, 0xb7, + 0x11, 0xb5, 0x3c, 0x3c, 0x62, 0x98, 0xb8, 0xb1, 0x97, 0x39, 0x7d, 0x36, 0x24, 0xef, 0x82, 0xff, + 0xa9, 0x6f, 0x1e, 0x21, 0x8b, 0xf5, 0x2e, 0x5d, 0x58, 0x8a, 0x5d, 0xd8, 0x0a, 0x03, 0xa5, 0xc2, + 0x2b, 0xbb, 0x02, 0x81, 0x7a, 0x51, 0xc4, 0x3a, 0x89, 0x29, 0xfb, 0xa0, 0x44, 0x7d, 0x93, 0x32, + 0xcc, 0x7c, 0x86, 0x66, 0xc8, 0x32, 0x31, 0x99, 0x12, 0x06, 0xca, 0xed, 0x84, 0x8c, 0x9a, 0x8b, + 0x28, 0xa8, 0xcb, 0x97, 0x9b, 0xa7, 0x94, 0xaf, 0x41, 0x01, 0xbb, 0x98, 0x61, 0xc3, 0xe9, 0x89, + 0x0b, 0xb5, 0xfc, 0xdb, 0x0b, 0x75, 0x47, 0x78, 0x5a, 0xe6, 0xc9, 0xe6, 0xf7, 0x43, 0xfd, 0x3f, + 0x11, 0xe0, 0xe8, 0x9d, 0xcc, 0xbb, 0x13, 0x25, 0x05, 0x7f, 0x48, 0xa0, 0x78, 0xc0, 0xdb, 0xef, + 0x9f, 0x0d, 0x7d, 0x08, 0x32, 0x23, 0xc7, 0x70, 0x63, 0x0f, 0xf3, 0xad, 0x2d, 0x95, 0x77, 0xbb, + 0x9a, 0x74, 0xb7, 0xe8, 0x76, 0xb5, 0xeb, 0x18, 0xae, 0xb8, 0xfc, 0x31, 0x5e, 0x3e, 0x02, 0x65, + 0x81, 0xb1, 0x7b, 0x73, 0xcd, 0x9a, 0xf9, 0x45, 0x03, 0xd4, 0xc3, 0x40, 0xd9, 0xe2, 0x42, 0xaf, + 0xdd, 0x0c, 0xf5, 0xf5, 0x24, 0x3e, 0xf3, 0x84, 0xec, 0xac, 0x46, 0xaa, 0x3f, 0x9c, 0x28, 0xa9, + 0xef, 0x27, 0x8a, 0x14, 0x3d, 0x35, 0x59, 0xd1, 0xb9, 0x1d, 0x50, 0xf4, 0xd0, 0x18, 0x53, 0x4c, + 0xdc, 0x9e, 0xeb, 0x0f, 0x4d, 0xe4, 0xc5, 0xf2, 0x33, 0xed, 0x6a, 0x18, 0x28, 0xb7, 0x78, 0xa2, + 0x05, 0x00, 0xd4, 0x0b, 0x49, 0xe4, 0x59, 0x1c, 0x98, 0x23, 0x11, 0xc7, 0x96, 0xbe, 0x91, 0x24, + 0x39, 0x97, 0x29, 0x89, 0x38, 0x98, 0x95, 0xa4, 0x44, 0xf8, 0x14, 0x64, 0xbb, 0x86, 0x67, 0x0c, + 0x69, 0x44, 0x6c, 0x38, 0x0e, 0x79, 0x3b, 0x15, 0x49, 0x2b, 0x52, 0x7d, 0xa9, 0x91, 0x9b, 0x25, + 0x5e, 0x00, 0x40, 0xbd, 0x20, 0x22, 0x5c, 0x3f, 0x6d, 0xef, 0x9f, 0x9e, 0xd7, 0xa4, 0xb3, 0xf3, + 0x9a, 0xf4, 0xed, 0xbc, 0x26, 0xbd, 0xbf, 0xa8, 0xa5, 0xce, 0x2e, 0x6a, 0xa9, 0xaf, 0x17, 0xb5, + 0xd4, 0xab, 0x47, 0x7d, 0xcc, 0x06, 0xbe, 0xa9, 0x5a, 0x64, 0xa8, 0x89, 0x37, 0x9a, 0x7f, 0xb6, + 0xa9, 0xfd, 0x46, 0x3b, 0xd6, 0xa6, 0x7f, 0x87, 0xfb, 0xad, 0x6d, 0xf1, 0x83, 0x60, 0x93, 0x11, + 0xa2, 0x66, 0x36, 0x3e, 0x93, 0x07, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x66, 0x9c, 0xf8, 0xf8, + 0x40, 0x06, 0x00, 0x00, +} + +func (this *UpgradeProposal) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*UpgradeProposal) + if !ok { + that2, ok := that.(UpgradeProposal) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Title != that1.Title { + return false + } + if this.Description != that1.Description { + return false + } + if !this.Plan.Equal(&that1.Plan) { + return false + } + if !this.UpgradedClientState.Equal(that1.UpgradedClientState) { + return false + } + return true } - func (m *IdentifiedClientState) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -584,6 +671,65 @@ func (m *ClientUpdateProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *UpgradeProposal) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UpgradeProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpgradeProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UpgradedClientState != nil { + { + size, err := m.UpgradedClientState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintClient(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + { + size, err := m.Plan.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintClient(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintClient(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintClient(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Height) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -738,6 +884,29 @@ func (m *ClientUpdateProposal) Size() (n int) { return n } +func (m *UpgradeProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovClient(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovClient(uint64(l)) + } + l = m.Plan.Size() + n += 1 + l + sovClient(uint64(l)) + if m.UpgradedClientState != nil { + l = m.UpgradedClientState.Size() + n += 1 + l + sovClient(uint64(l)) + } + return n +} + func (m *Height) Size() (n int) { if m == nil { return 0 @@ -1338,6 +1507,189 @@ func (m *ClientUpdateProposal) Unmarshal(dAtA []byte) error { } return nil } +func (m *UpgradeProposal) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UpgradeProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpgradeProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthClient + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthClient + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthClient + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthClient + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Plan", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthClient + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthClient + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Plan.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradedClientState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthClient + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthClient + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UpgradedClientState == nil { + m.UpgradedClientState = &types.Any{} + } + if err := m.UpgradedClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipClient(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthClient + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Height) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/ibc/core/02-client/types/codec.go b/x/ibc/core/02-client/types/codec.go index 59a15832bec1..8f8ab56112c7 100644 --- a/x/ibc/core/02-client/types/codec.go +++ b/x/ibc/core/02-client/types/codec.go @@ -37,6 +37,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations( (*govtypes.Content)(nil), &ClientUpdateProposal{}, + &UpgradeProposal{}, ) registry.RegisterImplementations( (*sdk.Msg)(nil), diff --git a/x/ibc/core/02-client/types/errors.go b/x/ibc/core/02-client/types/errors.go index 5b44cd522211..8a956f868730 100644 --- a/x/ibc/core/02-client/types/errors.go +++ b/x/ibc/core/02-client/types/errors.go @@ -32,4 +32,5 @@ var ( ErrInvalidUpgradeClient = sdkerrors.Register(SubModuleName, 25, "invalid client upgrade") ErrInvalidHeight = sdkerrors.Register(SubModuleName, 26, "invalid height") ErrInvalidSubstitute = sdkerrors.Register(SubModuleName, 27, "invalid client state substitute") + ErrInvalidUpgradeProposal = sdkerrors.Register(SubModuleName, 28, "invalid upgrade proposal") ) diff --git a/x/ibc/core/02-client/types/expected_keepers.go b/x/ibc/core/02-client/types/expected_keepers.go index defc81506b1d..ad007fb8011c 100644 --- a/x/ibc/core/02-client/types/expected_keepers.go +++ b/x/ibc/core/02-client/types/expected_keepers.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // StakingKeeper expected staking keeper @@ -12,3 +13,13 @@ type StakingKeeper interface { GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) UnbondingTime(ctx sdk.Context) time.Duration } + +// UpgradeKeeper expected upgrade keeper +type UpgradeKeeper interface { + ClearIBCState(ctx sdk.Context, lastHeight int64) + GetUpgradePlan(ctx sdk.Context) (plan upgradetypes.Plan, havePlan bool) + GetUpgradedClient(ctx sdk.Context, height int64) ([]byte, bool) + SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, bz []byte) error + SetUpgradedClient(ctx sdk.Context, planHeight int64, bz []byte) error + ScheduleUpgrade(ctx sdk.Context, plan upgradetypes.Plan) error +} diff --git a/x/ibc/core/02-client/types/proposal.go b/x/ibc/core/02-client/types/proposal.go index 95b10aaf408e..ed67e45425c4 100644 --- a/x/ibc/core/02-client/types/proposal.go +++ b/x/ibc/core/02-client/types/proposal.go @@ -1,23 +1,34 @@ package types import ( + "fmt" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) const ( // ProposalTypeClientUpdate defines the type for a ClientUpdateProposal ProposalTypeClientUpdate = "ClientUpdate" + ProposalTypeUpgrade = "IBCUpgrade" ) -var _ govtypes.Content = &ClientUpdateProposal{} +var ( + _ govtypes.Content = &ClientUpdateProposal{} + _ govtypes.Content = &UpgradeProposal{} + _ codectypes.UnpackInterfacesMessage = &UpgradeProposal{} +) func init() { govtypes.RegisterProposalType(ProposalTypeClientUpdate) + govtypes.RegisterProposalType(ProposalTypeUpgrade) } // NewClientUpdateProposal creates a new client update proposal. -func NewClientUpdateProposal(title, description, subjectClientID, substituteClientID string, initialHeight Height) *ClientUpdateProposal { +func NewClientUpdateProposal(title, description, subjectClientID, substituteClientID string, initialHeight Height) govtypes.Content { return &ClientUpdateProposal{ Title: title, Description: description, @@ -62,3 +73,82 @@ func (cup *ClientUpdateProposal) ValidateBasic() error { return nil } + +// NewUpgradeProposal creates a new IBC breaking upgrade proposal. +func NewUpgradeProposal(title, description string, plan upgradetypes.Plan, upgradedClientState exported.ClientState) (govtypes.Content, error) { + any, err := PackClientState(upgradedClientState) + if err != nil { + return nil, err + } + + return &UpgradeProposal{ + Title: title, + Description: description, + Plan: plan, + UpgradedClientState: any, + }, nil +} + +// GetTitle returns the title of a upgrade proposal. +func (up *UpgradeProposal) GetTitle() string { return up.Title } + +// GetDescription returns the description of a upgrade proposal. +func (up *UpgradeProposal) GetDescription() string { return up.Description } + +// ProposalRoute returns the routing key of a upgrade proposal. +func (up *UpgradeProposal) ProposalRoute() string { return RouterKey } + +// ProposalType returns the upgrade proposal type. +func (up *UpgradeProposal) ProposalType() string { return ProposalTypeUpgrade } + +// ValidateBasic runs basic stateless validity checks +func (up *UpgradeProposal) ValidateBasic() error { + if err := govtypes.ValidateAbstract(up); err != nil { + return err + } + + if err := up.Plan.ValidateBasic(); err != nil { + return err + } + + if up.Plan.Time.Unix() > 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeProposal, "IBC chain upgrades must only set height") + } + + if up.Plan.Height <= 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeProposal, "IBC chain upgrades must set a positive height") + } + + if up.UpgradedClientState == nil { + return sdkerrors.Wrap(ErrInvalidUpgradeProposal, "upgraded client state cannot be nil") + } + + _, err := UnpackClientState(up.UpgradedClientState) + if err != nil { + return sdkerrors.Wrap(err, "failed to unpack upgraded client state") + } + + return nil +} + +// String returns the string representation of the UpgradeProposal. +func (up UpgradeProposal) String() string { + var upgradedClientStr string + upgradedClient, err := UnpackClientState(up.UpgradedClientState) + if err != nil { + upgradedClientStr = "invalid IBC Client State" + } else { + upgradedClientStr = upgradedClient.String() + } + + return fmt.Sprintf(`IBC Upgrade Proposal + Title: %s + Description: %s + %s + Upgraded IBC Client: %s`, up.Title, up.Description, up.Plan, upgradedClientStr) +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (up UpgradeProposal) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + return unpacker.UnpackAny(up.UpgradedClientState, new(exported.ClientState)) +} diff --git a/x/ibc/core/02-client/types/proposal_test.go b/x/ibc/core/02-client/types/proposal_test.go index 597e5cf8f801..a7337081abd3 100644 --- a/x/ibc/core/02-client/types/proposal_test.go +++ b/x/ibc/core/02-client/types/proposal_test.go @@ -1,12 +1,17 @@ package types_test import ( + "fmt" + "time" + "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) func (suite *TypesTestSuite) TestValidateBasic() { @@ -76,7 +81,8 @@ func (suite *TypesTestSuite) TestMarshalClientUpdateProposalProposal() { cdc := codec.NewProtoCodec(ir) // marshal message - bz, err := cdc.MarshalJSON(proposal) + content := proposal.(*types.ClientUpdateProposal) + bz, err := cdc.MarshalJSON(content) suite.Require().NoError(err) // unmarshal proposal @@ -84,3 +90,145 @@ func (suite *TypesTestSuite) TestMarshalClientUpdateProposalProposal() { err = cdc.UnmarshalJSON(bz, newProposal) suite.Require().NoError(err) } + +func (suite *TypesTestSuite) TestUpgradeProposalValidateBasic() { + var ( + proposal govtypes.Content + err error + ) + + client, _ := suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) + cs := suite.chainA.GetClientState(client) + plan := upgradetypes.Plan{ + Name: "ibc upgrade", + Height: 1000, + } + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", func() { + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, cs) + suite.Require().NoError(err) + }, true, + }, + { + "fails validate abstract - empty title", func() { + proposal, err = types.NewUpgradeProposal("", ibctesting.Description, plan, cs) + suite.Require().NoError(err) + + }, false, + }, + { + "fails plan validate basic, height and time is 0", func() { + invalidPlan := upgradetypes.Plan{Name: "ibc upgrade"} + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, invalidPlan, cs) + suite.Require().NoError(err) + }, false, + }, + { + "plan height is zero", func() { + invalidPlan := upgradetypes.Plan{Name: "ibc upgrade", Height: 0} + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, invalidPlan, cs) + suite.Require().NoError(err) + }, false, + }, + { + "plan time is not set to 0", func() { + invalidPlan := upgradetypes.Plan{Name: "ibc upgrade", Time: time.Now()} + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, invalidPlan, cs) + suite.Require().NoError(err) + }, false, + }, + { + "client state is nil", func() { + proposal = &types.UpgradeProposal{ + Title: ibctesting.Title, + Description: ibctesting.Description, + Plan: plan, + UpgradedClientState: nil, + } + }, false, + }, + { + "failed to unpack client state", func() { + any, err := types.PackConsensusState(&ibctmtypes.ConsensusState{}) + suite.Require().NoError(err) + + proposal = &types.UpgradeProposal{ + Title: ibctesting.Title, + Description: ibctesting.Description, + Plan: plan, + UpgradedClientState: any, + } + }, false, + }, + } + + for _, tc := range testCases { + + tc.malleate() + + err := proposal.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().Error(err, tc.name) + } + } +} + +// tests an upgrade proposal can be marshaled and unmarshaled, and the +// client state can be unpacked +func (suite *TypesTestSuite) TestMarshalUpgradeProposal() { + // create proposal + plan := upgradetypes.Plan{ + Name: "upgrade ibc", + Height: 1000, + } + content, err := types.NewUpgradeProposal("title", "description", plan, &ibctmtypes.ClientState{}) + suite.Require().NoError(err) + + up, ok := content.(*types.UpgradeProposal) + suite.Require().True(ok) + + // create codec + ir := codectypes.NewInterfaceRegistry() + types.RegisterInterfaces(ir) + govtypes.RegisterInterfaces(ir) + ibctmtypes.RegisterInterfaces(ir) + cdc := codec.NewProtoCodec(ir) + + // marshal message + bz, err := cdc.MarshalJSON(up) + suite.Require().NoError(err) + + // unmarshal proposal + newUp := &types.UpgradeProposal{} + err = cdc.UnmarshalJSON(bz, newUp) + suite.Require().NoError(err) + + // unpack client state + _, err = types.UnpackClientState(newUp.UpgradedClientState) + suite.Require().NoError(err) + +} + +func (suite *TypesTestSuite) TestUpgradeString() { + plan := upgradetypes.Plan{ + Name: "ibc upgrade", + Info: "https://foo.bar/baz", + Height: 1000, + } + + proposal, err := types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, &ibctmtypes.ClientState{}) + suite.Require().NoError(err) + + expect := fmt.Sprintf("IBC Upgrade Proposal\n Title: title\n Description: description\n Upgrade Plan\n Name: ibc upgrade\n Height: 1000\n Info: https://foo.bar/baz.\n Upgraded IBC Client: %s", &ibctmtypes.ClientState{}) + + suite.Require().Equal(expect, proposal.String()) +} diff --git a/x/ibc/core/02-client/types/query.pb.go b/x/ibc/core/02-client/types/query.pb.go index 651becb899ae..27c5cb884140 100644 --- a/x/ibc/core/02-client/types/query.pb.go +++ b/x/ibc/core/02-client/types/query.pb.go @@ -583,6 +583,110 @@ func (m *QueryClientParamsResponse) GetParams() *Params { return nil } +// QueryUpgradedClientStateRequest is the request type for the Query/UpgradedClientState RPC +// method +type QueryUpgradedClientStateRequest struct { + // client state unique identifier + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // plan height of the current chain must be sent in request + // as this is the height under which upgraded client state is stored + PlanHeight int64 `protobuf:"varint,2,opt,name=plan_height,json=planHeight,proto3" json:"plan_height,omitempty"` +} + +func (m *QueryUpgradedClientStateRequest) Reset() { *m = QueryUpgradedClientStateRequest{} } +func (m *QueryUpgradedClientStateRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradedClientStateRequest) ProtoMessage() {} +func (*QueryUpgradedClientStateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dc42cdfd1d52d76e, []int{10} +} +func (m *QueryUpgradedClientStateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradedClientStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradedClientStateRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUpgradedClientStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradedClientStateRequest.Merge(m, src) +} +func (m *QueryUpgradedClientStateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradedClientStateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradedClientStateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradedClientStateRequest proto.InternalMessageInfo + +func (m *QueryUpgradedClientStateRequest) GetClientId() string { + if m != nil { + return m.ClientId + } + return "" +} + +func (m *QueryUpgradedClientStateRequest) GetPlanHeight() int64 { + if m != nil { + return m.PlanHeight + } + return 0 +} + +// QueryUpgradedClientStateResponse is the response type for the Query/UpgradedClientState RPC +// method. +type QueryUpgradedClientStateResponse struct { + // client state associated with the request identifier + UpgradedClientState *types.Any `protobuf:"bytes,1,opt,name=upgraded_client_state,json=upgradedClientState,proto3" json:"upgraded_client_state,omitempty"` +} + +func (m *QueryUpgradedClientStateResponse) Reset() { *m = QueryUpgradedClientStateResponse{} } +func (m *QueryUpgradedClientStateResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradedClientStateResponse) ProtoMessage() {} +func (*QueryUpgradedClientStateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dc42cdfd1d52d76e, []int{11} +} +func (m *QueryUpgradedClientStateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradedClientStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradedClientStateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUpgradedClientStateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradedClientStateResponse.Merge(m, src) +} +func (m *QueryUpgradedClientStateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradedClientStateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradedClientStateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradedClientStateResponse proto.InternalMessageInfo + +func (m *QueryUpgradedClientStateResponse) GetUpgradedClientState() *types.Any { + if m != nil { + return m.UpgradedClientState + } + return nil +} + func init() { proto.RegisterType((*QueryClientStateRequest)(nil), "ibc.core.client.v1.QueryClientStateRequest") proto.RegisterType((*QueryClientStateResponse)(nil), "ibc.core.client.v1.QueryClientStateResponse") @@ -594,64 +698,71 @@ func init() { proto.RegisterType((*QueryConsensusStatesResponse)(nil), "ibc.core.client.v1.QueryConsensusStatesResponse") proto.RegisterType((*QueryClientParamsRequest)(nil), "ibc.core.client.v1.QueryClientParamsRequest") proto.RegisterType((*QueryClientParamsResponse)(nil), "ibc.core.client.v1.QueryClientParamsResponse") + proto.RegisterType((*QueryUpgradedClientStateRequest)(nil), "ibc.core.client.v1.QueryUpgradedClientStateRequest") + proto.RegisterType((*QueryUpgradedClientStateResponse)(nil), "ibc.core.client.v1.QueryUpgradedClientStateResponse") } func init() { proto.RegisterFile("ibc/core/client/v1/query.proto", fileDescriptor_dc42cdfd1d52d76e) } var fileDescriptor_dc42cdfd1d52d76e = []byte{ - // 824 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x4f, 0xdb, 0x48, - 0x18, 0xce, 0xf0, 0x25, 0x98, 0x04, 0xb2, 0x1a, 0xa1, 0xdd, 0x60, 0x90, 0x89, 0xbc, 0x12, 0x64, - 0x77, 0x61, 0x86, 0x64, 0x3f, 0x90, 0x56, 0xe2, 0xb0, 0x20, 0xb1, 0xe5, 0xd2, 0x82, 0x7b, 0xa8, - 0x54, 0xa9, 0x42, 0xb6, 0x33, 0x38, 0x16, 0xc4, 0x13, 0x32, 0x4e, 0x54, 0x84, 0xb8, 0xf0, 0x07, - 0x5a, 0xa9, 0xc7, 0x5e, 0x7b, 0xea, 0xa1, 0xaa, 0xd4, 0x43, 0xff, 0x41, 0xc5, 0x11, 0xa9, 0x3d, - 0xf4, 0xd4, 0x56, 0xc0, 0xbf, 0xe8, 0xa5, 0xf2, 0xcc, 0x18, 0xec, 0xc4, 0x08, 0x0b, 0xb5, 0xa7, - 0xd8, 0xef, 0xd7, 0x3c, 0xcf, 0xf3, 0xbe, 0xef, 0x38, 0x50, 0xf7, 0x6c, 0x87, 0x38, 0xac, 0x4d, - 0x89, 0xb3, 0xe7, 0x51, 0x3f, 0x20, 0xdd, 0x2a, 0xd9, 0xef, 0xd0, 0xf6, 0x01, 0x6e, 0xb5, 0x59, - 0xc0, 0x10, 0xf2, 0x6c, 0x07, 0x87, 0x7e, 0x2c, 0xfd, 0xb8, 0x5b, 0xd5, 0x7e, 0x77, 0x18, 0x6f, - 0x32, 0x4e, 0x6c, 0x8b, 0x53, 0x19, 0x4c, 0xba, 0x55, 0x9b, 0x06, 0x56, 0x95, 0xb4, 0x2c, 0xd7, - 0xf3, 0xad, 0xc0, 0x63, 0xbe, 0xcc, 0xd7, 0x66, 0x53, 0xea, 0xab, 0x4a, 0x32, 0x60, 0xca, 0x65, - 0xcc, 0xdd, 0xa3, 0x44, 0xbc, 0xd9, 0x9d, 0x1d, 0x62, 0xf9, 0xea, 0x6c, 0x6d, 0x46, 0xb9, 0xac, - 0x96, 0x47, 0x2c, 0xdf, 0x67, 0x81, 0x28, 0xcc, 0x95, 0x77, 0xd2, 0x65, 0x2e, 0x13, 0x8f, 0x24, - 0x7c, 0x92, 0x56, 0xe3, 0x1f, 0xf8, 0xcb, 0x56, 0x88, 0x68, 0x4d, 0x9c, 0x71, 0x3f, 0xb0, 0x02, - 0x6a, 0xd2, 0xfd, 0x0e, 0xe5, 0x01, 0x9a, 0x86, 0x63, 0xf2, 0xe4, 0x6d, 0xaf, 0x5e, 0x02, 0x65, - 0x50, 0x19, 0x33, 0x47, 0xa5, 0x61, 0xa3, 0x6e, 0xbc, 0x02, 0xb0, 0xd4, 0x9f, 0xc8, 0x5b, 0xcc, - 0xe7, 0x14, 0x2d, 0xc3, 0x82, 0xca, 0xe4, 0xa1, 0x5d, 0x24, 0xe7, 0x6b, 0x93, 0x58, 0xe2, 0xc3, - 0x11, 0x74, 0xfc, 0x9f, 0x7f, 0x60, 0xe6, 0x9d, 0xab, 0x02, 0x68, 0x12, 0x0e, 0xb7, 0xda, 0x8c, - 0xed, 0x94, 0x06, 0xca, 0xa0, 0x52, 0x30, 0xe5, 0x0b, 0x5a, 0x83, 0x05, 0xf1, 0xb0, 0xdd, 0xa0, - 0x9e, 0xdb, 0x08, 0x4a, 0x83, 0xa2, 0x9c, 0x86, 0xfb, 0xa5, 0xc6, 0x77, 0x44, 0xc4, 0xea, 0xd0, - 0xc9, 0xa7, 0xd9, 0x9c, 0x99, 0x17, 0x59, 0xd2, 0x64, 0xd8, 0xfd, 0x78, 0x79, 0xc4, 0x74, 0x1d, - 0xc2, 0xab, 0x46, 0x28, 0xb4, 0x73, 0x58, 0x76, 0x0d, 0x87, 0x5d, 0xc3, 0xb2, 0xc5, 0xaa, 0x6b, - 0x78, 0xd3, 0x72, 0x23, 0x95, 0xcc, 0x58, 0xa6, 0xf1, 0x01, 0xc0, 0xa9, 0x94, 0x43, 0x94, 0x2a, - 0x3e, 0x1c, 0x8f, 0xab, 0xc2, 0x4b, 0xa0, 0x3c, 0x58, 0xc9, 0xd7, 0x7e, 0x4b, 0xe3, 0xb1, 0x51, - 0xa7, 0x7e, 0xe0, 0xed, 0x78, 0xb4, 0x1e, 0x2b, 0xb5, 0xaa, 0x87, 0xb4, 0x5e, 0x7e, 0x9e, 0xfd, - 0x39, 0xd5, 0xcd, 0xcd, 0x42, 0x4c, 0x4b, 0x8e, 0xfe, 0x4f, 0xb0, 0x1a, 0x10, 0xac, 0xe6, 0x6f, - 0x64, 0x25, 0xc1, 0x26, 0x68, 0xbd, 0x06, 0x50, 0x93, 0xb4, 0x42, 0x97, 0xcf, 0x3b, 0x3c, 0xf3, - 0x9c, 0xa0, 0x79, 0x58, 0x6c, 0xd3, 0xae, 0xc7, 0x3d, 0xe6, 0x6f, 0xfb, 0x9d, 0xa6, 0x4d, 0xdb, - 0x02, 0xc9, 0x90, 0x39, 0x11, 0x99, 0xef, 0x0a, 0x6b, 0x22, 0x30, 0xd6, 0xe7, 0x58, 0xa0, 0x6c, - 0x24, 0xfa, 0x15, 0x8e, 0xef, 0x85, 0xfc, 0x82, 0x28, 0x6c, 0xa8, 0x0c, 0x2a, 0xa3, 0x66, 0x41, - 0x1a, 0x55, 0xb7, 0xdf, 0x02, 0x38, 0x9d, 0x0a, 0x59, 0xf5, 0x62, 0x05, 0x16, 0x9d, 0xc8, 0x93, - 0x61, 0x48, 0x27, 0x9c, 0x44, 0x99, 0x1f, 0x39, 0xa7, 0xc7, 0xe9, 0xc8, 0x79, 0x26, 0xb5, 0xd7, - 0x53, 0x5a, 0x7e, 0x9b, 0x41, 0x7e, 0x07, 0xe0, 0x4c, 0x3a, 0x08, 0xa5, 0xdf, 0x23, 0xf8, 0x53, - 0x8f, 0x7e, 0xd1, 0x38, 0x2f, 0xa4, 0xd1, 0x4d, 0x96, 0x79, 0xe0, 0x05, 0x8d, 0x84, 0x00, 0xc5, - 0xa4, 0xbc, 0xdf, 0x71, 0x74, 0xb5, 0xc4, 0xd6, 0x6f, 0x5a, 0x6d, 0xab, 0x19, 0x29, 0x69, 0xdc, - 0x4b, 0x2c, 0x6b, 0xe4, 0x53, 0x04, 0x6b, 0x70, 0xa4, 0x25, 0x2c, 0x6a, 0x2e, 0x52, 0xbb, 0xa8, - 0x72, 0x54, 0x64, 0xed, 0xeb, 0x08, 0x1c, 0x16, 0x15, 0xd1, 0x0b, 0x00, 0xf3, 0xb1, 0xcd, 0x44, - 0x7f, 0xa4, 0x65, 0x5f, 0x73, 0xef, 0x6a, 0x0b, 0xd9, 0x82, 0x25, 0x50, 0xe3, 0xdf, 0xe3, 0xf7, - 0x17, 0xcf, 0x06, 0xfe, 0x42, 0x35, 0xd2, 0xff, 0xe5, 0x90, 0xdf, 0x98, 0xc4, 0xa5, 0x43, 0x0e, - 0x2f, 0xa7, 0xe7, 0x08, 0x3d, 0x07, 0xb0, 0x10, 0xbf, 0x40, 0x50, 0xa6, 0xa3, 0x23, 0x01, 0xb5, - 0xc5, 0x8c, 0xd1, 0x0a, 0x29, 0x16, 0x48, 0x2b, 0x68, 0x2e, 0x1b, 0x52, 0x74, 0x01, 0xe0, 0x44, - 0x72, 0x70, 0x10, 0xbe, 0xfe, 0xc4, 0xb4, 0xab, 0x49, 0x23, 0x99, 0xe3, 0x15, 0xc6, 0x7d, 0x81, - 0x71, 0x17, 0x79, 0xd7, 0x63, 0xec, 0x19, 0xfb, 0xb8, 0xa0, 0x24, 0xba, 0xaa, 0xc8, 0x61, 0xcf, - 0xa5, 0x77, 0x44, 0xe4, 0x9d, 0x10, 0x73, 0x48, 0xc3, 0x11, 0x7a, 0x03, 0x60, 0xb1, 0x67, 0xcd, - 0x50, 0x56, 0xdc, 0x97, 0xad, 0x58, 0xca, 0x9e, 0xa0, 0x98, 0xae, 0x08, 0xa6, 0xcb, 0xe8, 0xef, - 0x5b, 0x31, 0x45, 0x4f, 0x2e, 0x47, 0x47, 0x2e, 0xc1, 0x8d, 0xa3, 0x93, 0xd8, 0xbd, 0x1b, 0x47, - 0x27, 0xb9, 0x8d, 0x86, 0x21, 0xc0, 0xce, 0x20, 0x4d, 0x82, 0x4d, 0xe2, 0x94, 0xdb, 0xb7, 0xba, - 0x75, 0x72, 0xa6, 0x83, 0xd3, 0x33, 0x1d, 0x7c, 0x39, 0xd3, 0xc1, 0xd3, 0x73, 0x3d, 0x77, 0x7a, - 0xae, 0xe7, 0x3e, 0x9e, 0xeb, 0xb9, 0x87, 0xcb, 0xae, 0x17, 0x34, 0x3a, 0x36, 0x76, 0x58, 0x93, - 0xa8, 0xbf, 0x62, 0xf2, 0x67, 0x91, 0xd7, 0x77, 0xc9, 0xe3, 0x2b, 0x01, 0x96, 0x6a, 0x8b, 0xaa, - 0x76, 0x70, 0xd0, 0xa2, 0xdc, 0x1e, 0x11, 0x1f, 0x81, 0x3f, 0xbf, 0x05, 0x00, 0x00, 0xff, 0xff, - 0xa7, 0x0d, 0x7c, 0x62, 0xf5, 0x09, 0x00, 0x00, + // 909 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x8f, 0xdb, 0x44, + 0x18, 0xce, 0xec, 0x6e, 0xab, 0xed, 0x24, 0xdd, 0xa0, 0xe9, 0x02, 0xa9, 0xbb, 0x72, 0x22, 0x23, + 0xb5, 0x01, 0xba, 0x33, 0x4d, 0x5a, 0xba, 0x08, 0xa9, 0x48, 0x6c, 0xa5, 0xd2, 0x5e, 0xa0, 0x35, + 0x42, 0x48, 0x48, 0x28, 0xb2, 0x9d, 0x59, 0xc7, 0x6a, 0xe2, 0xf1, 0x7a, 0xec, 0x88, 0x55, 0xb5, + 0x97, 0xfe, 0x01, 0x90, 0x38, 0x72, 0xe5, 0xc4, 0x01, 0x21, 0x71, 0xe0, 0x86, 0x38, 0xa1, 0x1e, + 0x2b, 0xc1, 0x81, 0x13, 0xa0, 0xdd, 0xfe, 0x10, 0xe4, 0x99, 0x71, 0xd6, 0x93, 0x38, 0x5a, 0xb3, + 0xa2, 0xa7, 0xd8, 0xef, 0xe7, 0xf3, 0x3e, 0xef, 0x87, 0x03, 0xcd, 0xc0, 0xf5, 0x88, 0xc7, 0x62, + 0x4a, 0xbc, 0x71, 0x40, 0xc3, 0x84, 0x4c, 0x7b, 0x64, 0x3f, 0xa5, 0xf1, 0x01, 0x8e, 0x62, 0x96, + 0x30, 0x84, 0x02, 0xd7, 0xc3, 0x99, 0x1e, 0x4b, 0x3d, 0x9e, 0xf6, 0x8c, 0xb7, 0x3c, 0xc6, 0x27, + 0x8c, 0x13, 0xd7, 0xe1, 0x54, 0x1a, 0x93, 0x69, 0xcf, 0xa5, 0x89, 0xd3, 0x23, 0x91, 0xe3, 0x07, + 0xa1, 0x93, 0x04, 0x2c, 0x94, 0xfe, 0x46, 0xbb, 0x24, 0xbe, 0x8a, 0x24, 0x0d, 0x2e, 0xfb, 0x8c, + 0xf9, 0x63, 0x4a, 0xc4, 0x9b, 0x9b, 0xee, 0x11, 0x27, 0x54, 0xb9, 0x8d, 0x2d, 0xa5, 0x72, 0xa2, + 0x80, 0x38, 0x61, 0xc8, 0x12, 0x11, 0x98, 0x2b, 0xed, 0xa6, 0xcf, 0x7c, 0x26, 0x1e, 0x49, 0xf6, + 0x24, 0xa5, 0xd6, 0x6d, 0xf8, 0xfa, 0xa3, 0x0c, 0xd1, 0x5d, 0x91, 0xe3, 0x93, 0xc4, 0x49, 0xa8, + 0x4d, 0xf7, 0x53, 0xca, 0x13, 0x74, 0x05, 0x5e, 0x90, 0x99, 0x07, 0xc1, 0xb0, 0x05, 0x3a, 0xa0, + 0x7b, 0xc1, 0x5e, 0x97, 0x82, 0x07, 0x43, 0xeb, 0x07, 0x00, 0x5b, 0x8b, 0x8e, 0x3c, 0x62, 0x21, + 0xa7, 0x68, 0x07, 0x36, 0x94, 0x27, 0xcf, 0xe4, 0xc2, 0xb9, 0xde, 0xdf, 0xc4, 0x12, 0x1f, 0xce, + 0xa1, 0xe3, 0x0f, 0xc2, 0x03, 0xbb, 0xee, 0x9d, 0x04, 0x40, 0x9b, 0xf0, 0x5c, 0x14, 0x33, 0xb6, + 0xd7, 0x5a, 0xe9, 0x80, 0x6e, 0xc3, 0x96, 0x2f, 0xe8, 0x2e, 0x6c, 0x88, 0x87, 0xc1, 0x88, 0x06, + 0xfe, 0x28, 0x69, 0xad, 0x8a, 0x70, 0x06, 0x5e, 0xa4, 0x1a, 0xdf, 0x17, 0x16, 0xbb, 0x6b, 0xcf, + 0xfe, 0x6a, 0xd7, 0xec, 0xba, 0xf0, 0x92, 0x22, 0xcb, 0x5d, 0xc4, 0xcb, 0xf3, 0x4a, 0xef, 0x41, + 0x78, 0xd2, 0x08, 0x85, 0xf6, 0x2a, 0x96, 0x5d, 0xc3, 0x59, 0xd7, 0xb0, 0x6c, 0xb1, 0xea, 0x1a, + 0x7e, 0xe8, 0xf8, 0x39, 0x4b, 0x76, 0xc1, 0xd3, 0xfa, 0x03, 0xc0, 0xcb, 0x25, 0x49, 0x14, 0x2b, + 0x21, 0xbc, 0x58, 0x64, 0x85, 0xb7, 0x40, 0x67, 0xb5, 0x5b, 0xef, 0xbf, 0x59, 0x56, 0xc7, 0x83, + 0x21, 0x0d, 0x93, 0x60, 0x2f, 0xa0, 0xc3, 0x42, 0xa8, 0x5d, 0x33, 0x2b, 0xeb, 0xfb, 0xbf, 0xdb, + 0xaf, 0x95, 0xaa, 0xb9, 0xdd, 0x28, 0x70, 0xc9, 0xd1, 0x87, 0x5a, 0x55, 0x2b, 0xa2, 0xaa, 0x6b, + 0xa7, 0x56, 0x25, 0xc1, 0x6a, 0x65, 0xfd, 0x08, 0xa0, 0x21, 0xcb, 0xca, 0x54, 0x21, 0x4f, 0x79, + 0xe5, 0x39, 0x41, 0xd7, 0x60, 0x33, 0xa6, 0xd3, 0x80, 0x07, 0x2c, 0x1c, 0x84, 0xe9, 0xc4, 0xa5, + 0xb1, 0x40, 0xb2, 0x66, 0x6f, 0xe4, 0xe2, 0x8f, 0x84, 0x54, 0x33, 0x2c, 0xf4, 0xb9, 0x60, 0x28, + 0x1b, 0x89, 0xde, 0x80, 0x17, 0xc7, 0x59, 0x7d, 0x49, 0x6e, 0xb6, 0xd6, 0x01, 0xdd, 0x75, 0xbb, + 0x21, 0x85, 0xaa, 0xdb, 0x3f, 0x03, 0x78, 0xa5, 0x14, 0xb2, 0xea, 0xc5, 0x1d, 0xd8, 0xf4, 0x72, + 0x4d, 0x85, 0x21, 0xdd, 0xf0, 0xb4, 0x30, 0x2f, 0x73, 0x4e, 0x9f, 0x96, 0x23, 0xe7, 0x95, 0xd8, + 0xbe, 0x57, 0xd2, 0xf2, 0xb3, 0x0c, 0xf2, 0x6f, 0x00, 0x6e, 0x95, 0x83, 0x50, 0xfc, 0x7d, 0x01, + 0x5f, 0x99, 0xe3, 0x2f, 0x1f, 0xe7, 0xeb, 0x65, 0xe5, 0xea, 0x61, 0x3e, 0x0b, 0x92, 0x91, 0x46, + 0x40, 0x53, 0xa7, 0xf7, 0x7f, 0x1c, 0x5d, 0x43, 0xdb, 0xfa, 0x87, 0x4e, 0xec, 0x4c, 0x72, 0x26, + 0xad, 0x8f, 0xb5, 0x65, 0xcd, 0x75, 0xaa, 0xc0, 0x3e, 0x3c, 0x1f, 0x09, 0x89, 0x9a, 0x8b, 0xd2, + 0x2e, 0x2a, 0x1f, 0x65, 0x69, 0x0d, 0x60, 0x5b, 0x04, 0xfc, 0x34, 0xf2, 0x63, 0x67, 0xa8, 0xed, + 0x66, 0xa5, 0xee, 0xb5, 0x61, 0x3d, 0x1a, 0x3b, 0xb3, 0xf1, 0xcf, 0xca, 0x5e, 0xb5, 0x61, 0x26, + 0x52, 0xb3, 0x31, 0x86, 0x9d, 0xe5, 0x09, 0x14, 0xf0, 0xfb, 0xf0, 0xd5, 0x54, 0xa9, 0x07, 0x95, + 0x8f, 0xf0, 0xa5, 0x74, 0x31, 0x62, 0xff, 0x97, 0x75, 0x78, 0x4e, 0xa4, 0x43, 0xdf, 0x01, 0x58, + 0x2f, 0x68, 0xd0, 0xdb, 0x65, 0x64, 0x2c, 0xf9, 0x8c, 0x18, 0xd7, 0xab, 0x19, 0x4b, 0xf8, 0xd6, + 0x7b, 0x4f, 0x7f, 0x7f, 0xf1, 0xcd, 0xca, 0x2d, 0xd4, 0x27, 0x8b, 0x1f, 0x42, 0xf9, 0xc9, 0xd4, + 0x6e, 0x28, 0x79, 0x32, 0xa3, 0xf3, 0x10, 0x7d, 0x0b, 0x60, 0xa3, 0x78, 0x0f, 0x51, 0xa5, 0xd4, + 0xf9, 0x3c, 0x18, 0xdb, 0x15, 0xad, 0x15, 0x52, 0x2c, 0x90, 0x76, 0xd1, 0xd5, 0x6a, 0x48, 0xd1, + 0x0b, 0x00, 0x37, 0xf4, 0x3d, 0x40, 0x78, 0x79, 0xc6, 0xb2, 0x4b, 0x6b, 0x90, 0xca, 0xf6, 0x0a, + 0xe3, 0xbe, 0xc0, 0xf8, 0x18, 0x05, 0xcb, 0x31, 0xce, 0x6d, 0x71, 0x91, 0x50, 0x92, 0x5f, 0x5e, + 0xf2, 0x64, 0xee, 0x86, 0x1f, 0x12, 0x39, 0xa3, 0x05, 0x85, 0x14, 0x1c, 0xa2, 0x9f, 0x00, 0x6c, + 0xce, 0x5d, 0x0d, 0x54, 0x15, 0xf7, 0xac, 0x15, 0x37, 0xaa, 0x3b, 0xa8, 0x4a, 0xef, 0x88, 0x4a, + 0x77, 0xd0, 0x3b, 0x67, 0xaa, 0x14, 0x7d, 0x35, 0x1b, 0x1d, 0xb9, 0xd3, 0xa7, 0x8e, 0x8e, 0x76, + 0x4a, 0x4e, 0x1d, 0x1d, 0xfd, 0xb8, 0x58, 0x96, 0x00, 0xbb, 0x85, 0x0c, 0x09, 0x56, 0xc7, 0x29, + 0x8f, 0x09, 0xfa, 0x15, 0xc0, 0x4b, 0x25, 0x7b, 0x8e, 0x6e, 0x2e, 0x4d, 0xb5, 0xfc, 0xec, 0x18, + 0xb7, 0xfe, 0x9b, 0x93, 0x82, 0xf9, 0xbe, 0x80, 0xf9, 0x2e, 0xba, 0x5d, 0xc2, 0x29, 0x29, 0x3d, + 0x32, 0x1a, 0xa9, 0xbb, 0x8f, 0x9e, 0x1d, 0x99, 0xe0, 0xf9, 0x91, 0x09, 0xfe, 0x39, 0x32, 0xc1, + 0xd7, 0xc7, 0x66, 0xed, 0xf9, 0xb1, 0x59, 0xfb, 0xf3, 0xd8, 0xac, 0x7d, 0xbe, 0xe3, 0x07, 0xc9, + 0x28, 0x75, 0xb1, 0xc7, 0x26, 0x44, 0xfd, 0x39, 0x96, 0x3f, 0xdb, 0x7c, 0xf8, 0x98, 0x7c, 0x79, + 0x92, 0xef, 0x46, 0x7f, 0x5b, 0xa5, 0x4c, 0x0e, 0x22, 0xca, 0xdd, 0xf3, 0xe2, 0x6c, 0xdd, 0xfc, + 0x37, 0x00, 0x00, 0xff, 0xff, 0x66, 0x42, 0x78, 0x90, 0x87, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -678,6 +789,8 @@ type QueryClient interface { ConsensusStates(ctx context.Context, in *QueryConsensusStatesRequest, opts ...grpc.CallOption) (*QueryConsensusStatesResponse, error) // ClientParams queries all parameters of the ibc client. ClientParams(ctx context.Context, in *QueryClientParamsRequest, opts ...grpc.CallOption) (*QueryClientParamsResponse, error) + // UpgradedClientState queries an Upgraded IBC light client. + UpgradedClientState(ctx context.Context, in *QueryUpgradedClientStateRequest, opts ...grpc.CallOption) (*QueryUpgradedClientStateResponse, error) } type queryClient struct { @@ -733,6 +846,15 @@ func (c *queryClient) ClientParams(ctx context.Context, in *QueryClientParamsReq return out, nil } +func (c *queryClient) UpgradedClientState(ctx context.Context, in *QueryUpgradedClientStateRequest, opts ...grpc.CallOption) (*QueryUpgradedClientStateResponse, error) { + out := new(QueryUpgradedClientStateResponse) + err := c.cc.Invoke(ctx, "/ibc.core.client.v1.Query/UpgradedClientState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // ClientState queries an IBC light client. @@ -747,6 +869,8 @@ type QueryServer interface { ConsensusStates(context.Context, *QueryConsensusStatesRequest) (*QueryConsensusStatesResponse, error) // ClientParams queries all parameters of the ibc client. ClientParams(context.Context, *QueryClientParamsRequest) (*QueryClientParamsResponse, error) + // UpgradedClientState queries an Upgraded IBC light client. + UpgradedClientState(context.Context, *QueryUpgradedClientStateRequest) (*QueryUpgradedClientStateResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -768,6 +892,9 @@ func (*UnimplementedQueryServer) ConsensusStates(ctx context.Context, req *Query func (*UnimplementedQueryServer) ClientParams(ctx context.Context, req *QueryClientParamsRequest) (*QueryClientParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ClientParams not implemented") } +func (*UnimplementedQueryServer) UpgradedClientState(ctx context.Context, req *QueryUpgradedClientStateRequest) (*QueryUpgradedClientStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpgradedClientState not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -863,6 +990,24 @@ func _Query_ClientParams_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Query_UpgradedClientState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUpgradedClientStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UpgradedClientState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.client.v1.Query/UpgradedClientState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UpgradedClientState(ctx, req.(*QueryUpgradedClientStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "ibc.core.client.v1.Query", HandlerType: (*QueryServer)(nil), @@ -887,6 +1032,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ClientParams", Handler: _Query_ClientParams_Handler, }, + { + MethodName: "UpgradedClientState", + Handler: _Query_UpgradedClientState_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ibc/core/client/v1/query.proto", @@ -1309,6 +1458,76 @@ func (m *QueryClientParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *QueryUpgradedClientStateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUpgradedClientStateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradedClientStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PlanHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.PlanHeight)) + i-- + dAtA[i] = 0x10 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryUpgradedClientStateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUpgradedClientStateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradedClientStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UpgradedClientState != nil { + { + size, err := m.UpgradedClientState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1483,6 +1702,35 @@ func (m *QueryClientParamsResponse) Size() (n int) { return n } +func (m *QueryUpgradedClientStateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.PlanHeight != 0 { + n += 1 + sovQuery(uint64(m.PlanHeight)) + } + return n +} + +func (m *QueryUpgradedClientStateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UpgradedClientState != nil { + l = m.UpgradedClientState.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2597,6 +2845,193 @@ func (m *QueryClientParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryUpgradedClientStateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUpgradedClientStateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUpgradedClientStateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PlanHeight", wireType) + } + m.PlanHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PlanHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUpgradedClientStateResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUpgradedClientStateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUpgradedClientStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradedClientState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UpgradedClientState == nil { + m.UpgradedClientState = &types.Any{} + } + if err := m.UpgradedClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ibc/core/02-client/types/query.pb.gw.go b/x/ibc/core/02-client/types/query.pb.gw.go index 40bc6a85fdd0..9e36ecc18fde 100644 --- a/x/ibc/core/02-client/types/query.pb.gw.go +++ b/x/ibc/core/02-client/types/query.pb.gw.go @@ -327,6 +327,78 @@ func local_request_Query_ClientParams_0(ctx context.Context, marshaler runtime.M } +var ( + filter_Query_UpgradedClientState_0 = &utilities.DoubleArray{Encoding: map[string]int{"client_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_UpgradedClientState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradedClientStateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["client_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "client_id") + } + + protoReq.ClientId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UpgradedClientState_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpgradedClientState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UpgradedClientState_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradedClientStateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["client_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "client_id") + } + + protoReq.ClientId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UpgradedClientState_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpgradedClientState(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -433,6 +505,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_UpgradedClientState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_UpgradedClientState_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UpgradedClientState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -574,6 +666,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_UpgradedClientState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_UpgradedClientState_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UpgradedClientState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -587,6 +699,8 @@ var ( pattern_Query_ConsensusStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ClientParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ibc", "client", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_UpgradedClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "upgraded_client_states", "client_id"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -599,4 +713,6 @@ var ( forward_Query_ConsensusStates_0 = runtime.ForwardResponseMessage forward_Query_ClientParams_0 = runtime.ForwardResponseMessage + + forward_Query_UpgradedClientState_0 = runtime.ForwardResponseMessage ) diff --git a/x/ibc/core/keeper/grpc_query.go b/x/ibc/core/keeper/grpc_query.go index f406d2e86f00..3db15d3c0bc7 100644 --- a/x/ibc/core/keeper/grpc_query.go +++ b/x/ibc/core/keeper/grpc_query.go @@ -33,6 +33,11 @@ func (q Keeper) ClientParams(c context.Context, req *clienttypes.QueryClientPara return q.ClientKeeper.ClientParams(c, req) } +// UpgradedClientState implements the IBC QueryServer interface +func (q Keeper) UpgradedClientState(c context.Context, req *clienttypes.QueryUpgradedClientStateRequest) (*clienttypes.QueryUpgradedClientStateResponse, error) { + return q.ClientKeeper.UpgradedClientState(c, req) +} + // Connection implements the IBC QueryServer interface func (q Keeper) Connection(c context.Context, req *connectiontypes.QueryConnectionRequest) (*connectiontypes.QueryConnectionResponse, error) { return q.ConnectionKeeper.Connection(c, req) diff --git a/x/ibc/core/keeper/keeper.go b/x/ibc/core/keeper/keeper.go index 5f9abc382ecb..dab06caec27d 100644 --- a/x/ibc/core/keeper/keeper.go +++ b/x/ibc/core/keeper/keeper.go @@ -33,9 +33,10 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( cdc codec.BinaryMarshaler, key sdk.StoreKey, paramSpace paramtypes.Subspace, - stakingKeeper clienttypes.StakingKeeper, scopedKeeper capabilitykeeper.ScopedKeeper, + stakingKeeper clienttypes.StakingKeeper, upgradeKeeper clienttypes.UpgradeKeeper, + scopedKeeper capabilitykeeper.ScopedKeeper, ) *Keeper { - clientKeeper := clientkeeper.NewKeeper(cdc, key, paramSpace, stakingKeeper) + clientKeeper := clientkeeper.NewKeeper(cdc, key, paramSpace, stakingKeeper, upgradeKeeper) connectionKeeper := connectionkeeper.NewKeeper(cdc, key, clientKeeper) portKeeper := portkeeper.NewKeeper(scopedKeeper) channelKeeper := channelkeeper.NewKeeper(cdc, key, clientKeeper, connectionKeeper, portKeeper, scopedKeeper) diff --git a/x/ibc/core/keeper/msg_server_test.go b/x/ibc/core/keeper/msg_server_test.go index 1af4cdc18eb0..1c4b60010f7a 100644 --- a/x/ibc/core/keeper/msg_server_test.go +++ b/x/ibc/core/keeper/msg_server_test.go @@ -639,14 +639,18 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { // last Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + upgradedClientBz, err := clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) + upgradedConsStateBz, err := clienttypes.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) + suite.Require().NoError(err) + // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) suite.Require().NoError(err) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) @@ -676,14 +680,18 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { // last Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + upgradedClientBz, err := clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) + upgradedConsStateBz, err := clienttypes.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) + suite.Require().NoError(err) + // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) suite.Require().NoError(err) msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradedConsState, nil, nil, suite.chainA.SenderAccount.GetAddress()) diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade.go b/x/ibc/light-clients/07-tendermint/types/upgrade.go index 397e9cfd8374..161b725da16e 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade.go @@ -40,8 +40,8 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( upgradedClient.GetLatestHeight(), lastHeight) } - // counterparty chain must commit the upgraded client with all client-customizable fields zeroed out - // at the upgrade path specified by current client + // upgraded client state and consensus state must be IBC tendermint client state and consensus state + // this may be modified in the future to upgrade to a new IBC tendermint type // counterparty must also commit to the upgraded consensus state at a sub-path under the upgrade path specified tmUpgradeClient, ok := upgradedClient.(*ClientState) if !ok { diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go index 7be3a4943f33..8a7623f94301 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go @@ -15,6 +15,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight clienttypes.Height clientA string proofUpgradedClient, proofUpgradedConsState []byte + upgradedClientBz, upgradedConsStateBz []byte + err error ) testCases := []struct { @@ -25,18 +27,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "successful upgrade", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -57,16 +53,16 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedHeight := clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+2)) upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradedHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } + upgradedClient = upgradedClient.ZeroCustomFields() + upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -86,18 +82,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: upgrade height revision height is more than the current client revision height", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is 10 blocks from now lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+10)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -114,20 +104,43 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { expPass: false, }, { - name: "unsuccessful upgrade: chain-specified parameters do not match committed client", + name: "unsuccessful upgrade: committed client does not have zeroed custom fields", setup: func() { - + // non-zeroed upgrade client upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } + upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + // zero custom fields and store in upgrade store + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + // commit upgrade store changes and update clients + + suite.coordinator.CommitBlock(suite.chainB) + err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + suite.Require().NoError(err) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: chain-specified parameters do not match committed client", + setup: func() { // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // change upgradedClient client-specified parameters upgradedClient = types.NewClientState("wrongchainID", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, true) @@ -147,15 +160,9 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: client-specified parameters do not match previous client", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // change upgradedClient client-specified parameters upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) @@ -175,18 +182,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: relayer-submitted consensus state does not match counterparty-committed consensus state", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // change submitted upgradedConsensusState upgradedConsState = &types.ConsensusState{ @@ -210,11 +211,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: client proof unmarshal failed", setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) @@ -228,12 +225,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: consensus state proof unmarshal failed", setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) @@ -247,16 +239,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: client proof verification failed", setup: func() { - // create but do not store upgraded client - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } + // do not store upgraded client // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) @@ -269,16 +257,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: consensus state proof verification failed", setup: func() { - // create but do not store upgraded client - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } + // do not store upgraded client // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) @@ -291,17 +275,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: upgrade path is empty", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) // commit upgrade store changes and update clients @@ -325,17 +303,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: upgraded height is not greater than current height", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) // commit upgrade store changes and update clients @@ -354,17 +326,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: consensus state for upgrade height cannot be found", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) // commit upgrade store changes and update clients @@ -383,14 +349,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: client is expired", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) // commit upgrade store changes and update clients @@ -412,17 +372,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: updated unbonding period is equal to trusting period", setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } - // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) // commit upgrade store changes and update clients @@ -441,19 +395,17 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: final client is not valid", setup: func() { - // new client has smaller unbonding period such that old trusting period is no longer valid upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - upgradedConsState = &types.ConsensusState{ - NextValidatorsHash: []byte("nextValsHash"), - } + upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) // commit upgrade store changes and update clients @@ -478,6 +430,16 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { suite.SetupTest() clientA, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = upgradedClient.ZeroCustomFields() + upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + suite.Require().NoError(err) + + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + upgradedConsStateBz, err = clienttypes.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) + suite.Require().NoError(err) tc.setup() diff --git a/x/upgrade/abci.go b/x/upgrade/abci.go index fa95c4c4aa63..d346decb023c 100644 --- a/x/upgrade/abci.go +++ b/x/upgrade/abci.go @@ -10,8 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ) // BeginBlock will check if there is a scheduled plan and if it is ready to be executed. @@ -24,25 +22,11 @@ import ( // skipUpgradeHeightArray is a set of block heights for which the upgrade must be skipped func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) - plan, found := k.GetUpgradePlan(ctx) if !found { return } - // Once we are at the last block this chain will commit, set the upgraded consensus state - // so that IBC clients can use the last NextValidatorsHash as a trusted kernel for verifying - // headers on the next version of the chain. - // Set the time to the last block time of the current chain. - // In order for a client to upgrade successfully, the first block of the new chain must be committed - // within the trusting period of the last block time on this chain. - if plan.IsIBCPlan() && ctx.BlockHeight() == plan.Height-1 { - upgradedConsState := &ibctmtypes.ConsensusState{ - Timestamp: ctx.BlockTime(), - NextValidatorsHash: ctx.BlockHeader().NextValidatorsHash, - } - k.SetUpgradedConsensusState(ctx, plan.Height, upgradedConsState) - } // To make sure clear upgrade is executed at the same block if plan.ShouldExecute(ctx) { // If skip upgrade has been set for current height, we clear the upgrade plan diff --git a/x/upgrade/abci_test.go b/x/upgrade/abci_test.go index eb31857961bc..9eb0fc1a7ab9 100644 --- a/x/upgrade/abci_test.go +++ b/x/upgrade/abci_test.go @@ -21,8 +21,6 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/upgrade" "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/x/upgrade/types" @@ -120,59 +118,6 @@ func TestCanOverwriteScheduleUpgrade(t *testing.T) { VerifyDoUpgrade(t) } -func VerifyDoIBCLastBlock(t *testing.T) { - t.Log("Verify that chain committed to consensus state on the last height it will commit") - nextValsHash := []byte("nextValsHash") - newCtx := s.ctx.WithBlockHeader(tmproto.Header{ - Height: s.ctx.BlockHeight(), - NextValidatorsHash: nextValsHash, - }) - - req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} - s.module.BeginBlock(newCtx, req) - - // plan Height is at ctx.BlockHeight+1 - consState, err := s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()+1) - require.NoError(t, err) - require.Equal(t, &ibctmtypes.ConsensusState{Timestamp: newCtx.BlockTime(), NextValidatorsHash: nextValsHash}, consState) -} - -func VerifyDoIBCUpgrade(t *testing.T) { - t.Log("Verify that a panic happens at the upgrade time/height") - newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) - - // Check IBC state is set before upgrade using last height: s.ctx.BlockHeight() - cs, err := s.keeper.GetUpgradedClient(newCtx, s.ctx.BlockHeight()) - require.NoError(t, err, "could not retrieve upgraded client before upgrade plan is applied") - require.NotNil(t, cs, "IBC client is nil before upgrade") - - consState, err := s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) - require.NoError(t, err, "could not retrieve upgraded consensus state before upgrade plan is applied") - require.NotNil(t, consState, "IBC consensus state is nil before upgrade") - - req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} - require.Panics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - t.Log("Verify that the upgrade can be successfully applied with a handler") - s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan types.Plan) {}) - require.NotPanics(t, func() { - s.module.BeginBlock(newCtx, req) - }) - - VerifyCleared(t, newCtx) - - // Check IBC state is cleared after upgrade using last height: s.ctx.BlockHeight() - cs, err = s.keeper.GetUpgradedClient(newCtx, s.ctx.BlockHeight()) - require.Error(t, err, "retrieved upgraded client after upgrade plan is applied") - require.Nil(t, cs, "IBC client is not-nil after upgrade") - - consState, err = s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) - require.Error(t, err, "retrieved upgraded consensus state after upgrade plan is applied") - require.Nil(t, consState, "IBC consensus state is not-nil after upgrade") -} - func VerifyDoUpgrade(t *testing.T) { t.Log("Verify that a panic happens at the upgrade time/height") newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) @@ -280,27 +225,20 @@ func TestNoSpuriousUpgrades(t *testing.T) { } func TestPlanStringer(t *testing.T) { - clientState := &ibctmtypes.ClientState{ChainId: "gaiachain"} - cs, err := clienttypes.PackClientState(clientState) - require.NoError(t, err) - ti, err := time.Parse(time.RFC3339, "2020-01-01T00:00:00Z") require.Nil(t, err) require.Equal(t, `Upgrade Plan Name: test Time: 2020-01-01T00:00:00Z - Info: . - Upgraded IBC Client: no upgraded client provided`, types.Plan{Name: "test", Time: ti}.String()) + Info: .`, types.Plan{Name: "test", Time: ti}.String()) require.Equal(t, `Upgrade Plan Name: test Height: 100 - Info: . - Upgraded IBC Client: no upgraded client provided`, types.Plan{Name: "test", Height: 100}.String()) + Info: .`, types.Plan{Name: "test", Height: 100}.String()) require.Equal(t, fmt.Sprintf(`Upgrade Plan Name: test Height: 100 - Info: . - Upgraded IBC Client: %s`, clientState), types.Plan{Name: "test", Height: 100, UpgradedClientState: cs}.String()) + Info: .`), types.Plan{Name: "test", Height: 100}.String()) } func VerifyNotDone(t *testing.T, newCtx sdk.Context, name string) { @@ -467,27 +405,6 @@ func TestUpgradeWithoutSkip(t *testing.T) { VerifyDone(t, s.ctx, "test") } -func TestIBCUpgradeWithoutSkip(t *testing.T) { - s := setupTest(10, map[int64]bool{}) - cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) - require.NoError(t, err) - err = s.handler(s.ctx, &types.SoftwareUpgradeProposal{ - Title: "prop", - Plan: types.Plan{ - Name: "test", - Height: s.ctx.BlockHeight() + 1, - UpgradedClientState: cs, - }, - }) - require.Nil(t, err) - - t.Log("Verify if last height stores consensus state") - VerifyDoIBCLastBlock(t) - - VerifyDoUpgrade(t) - VerifyDone(t, s.ctx, "test") -} - func TestDumpUpgradeInfoToFile(t *testing.T) { s := setupTest(10, map[int64]bool{}) diff --git a/x/upgrade/keeper/grpc_query.go b/x/upgrade/keeper/grpc_query.go index 26e7860c8627..3806fcbb0480 100644 --- a/x/upgrade/keeper/grpc_query.go +++ b/x/upgrade/keeper/grpc_query.go @@ -4,7 +4,6 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -38,17 +37,12 @@ func (k Keeper) AppliedPlan(c context.Context, req *types.QueryAppliedPlanReques func (k Keeper) UpgradedConsensusState(c context.Context, req *types.QueryUpgradedConsensusStateRequest) (*types.QueryUpgradedConsensusStateResponse, error) { ctx := sdk.UnwrapSDKContext(c) - consState, err := k.GetUpgradedConsensusState(ctx, req.LastHeight) - if err != nil { - return nil, err - } - - cs, err := clienttypes.PackConsensusState(consState) - if err != nil { - return nil, err + consState, found := k.GetUpgradedConsensusState(ctx, req.LastHeight) + if !found { + return &types.QueryUpgradedConsensusStateResponse{}, nil } return &types.QueryUpgradedConsensusStateResponse{ - UpgradedConsensusState: cs, + UpgradedConsensusState: consState, }, nil } diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index 1092885bcb3f..e366ae09198e 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -16,8 +16,6 @@ import ( store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - ibcexported "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -75,84 +73,52 @@ func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error { store := ctx.KVStore(k.storeKey) // clear any old IBC state stored by previous plan - oldPlan, exists := k.GetUpgradePlan(ctx) - if exists && oldPlan.IsIBCPlan() { - k.ClearIBCState(ctx, oldPlan.Height-1) + oldPlan, found := k.GetUpgradePlan(ctx) + if found { + k.ClearIBCState(ctx, oldPlan.Height) } bz := k.cdc.MustMarshalBinaryBare(&plan) store.Set(types.PlanKey(), bz) - if plan.IsIBCPlan() { - // Set UpgradedClientState in store - clientState, err := clienttypes.UnpackClientState(plan.UpgradedClientState) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not unpack clientstate: %v", err) - } - // sets the new upgraded client in last height committed on this chain is at plan.Height, - // since the chain will panic at plan.Height and new chain will resume at plan.Height - return k.SetUpgradedClient(ctx, plan.Height, clientState) - } return nil } // SetUpgradedClient sets the expected upgraded client for the next version of this chain at the last height the current chain will commit. -func (k Keeper) SetUpgradedClient(ctx sdk.Context, planHeight int64, cs ibcexported.ClientState) error { +func (k Keeper) SetUpgradedClient(ctx sdk.Context, planHeight int64, bz []byte) error { store := ctx.KVStore(k.storeKey) - - // zero out any custom fields before setting - cs = cs.ZeroCustomFields() - bz, err := clienttypes.MarshalClientState(k.cdc, cs) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not marshal clientstate: %v", err) - } - store.Set(types.UpgradedClientKey(planHeight), bz) return nil } // GetUpgradedClient gets the expected upgraded client for the next version of this chain -func (k Keeper) GetUpgradedClient(ctx sdk.Context, height int64) (ibcexported.ClientState, error) { +func (k Keeper) GetUpgradedClient(ctx sdk.Context, height int64) ([]byte, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.UpgradedClientKey(height)) if len(bz) == 0 { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgraded client not found in store for height %d", height) + return nil, false } - clientState, err := clienttypes.UnmarshalClientState(k.cdc, bz) - if err != nil { - return nil, err - } - return clientState, nil + return bz, true } // SetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain // using the last height committed on this chain. -func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, cs ibcexported.ConsensusState) error { +func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, bz []byte) error { store := ctx.KVStore(k.storeKey) - bz, err := clienttypes.MarshalConsensusState(k.cdc, cs) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not marshal consensus state: %v", err) - } - store.Set(types.UpgradedConsStateKey(planHeight), bz) return nil } // GetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain -func (k Keeper) GetUpgradedConsensusState(ctx sdk.Context, lastHeight int64) (ibcexported.ConsensusState, error) { +func (k Keeper) GetUpgradedConsensusState(ctx sdk.Context, lastHeight int64) ([]byte, bool) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.UpgradedConsStateKey(lastHeight)) if len(bz) == 0 { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgraded consensus state not found in store for height: %d", lastHeight) - } - consState, err := clienttypes.UnmarshalConsensusState(k.cdc, bz) - if err != nil { - return nil, err + return nil, false } - return consState, nil + + return bz, true } // GetDoneHeight returns the height at which the given upgrade was executed @@ -174,8 +140,14 @@ func (k Keeper) ClearIBCState(ctx sdk.Context, lastHeight int64) { store.Delete(types.UpgradedConsStateKey(lastHeight)) } -// ClearUpgradePlan clears any schedule upgrade +// ClearUpgradePlan clears any schedule upgrade and associated IBC states. func (k Keeper) ClearUpgradePlan(ctx sdk.Context) { + // clear IBC states everytime upgrade plan is removed + oldPlan, found := k.GetUpgradePlan(ctx) + if found { + k.ClearIBCState(ctx, oldPlan.Height) + } + store := ctx.KVStore(k.storeKey) store.Delete(types.PlanKey()) } @@ -223,9 +195,7 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) { // Must clear IBC state after upgrade is applied as it is stored separately from the upgrade plan. // This will prevent resubmission of upgrade msg after upgrade is already completed. - if plan.IsIBCPlan() { - k.ClearIBCState(ctx, plan.Height-1) - } + k.ClearIBCState(ctx, plan.Height) k.ClearUpgradePlan(ctx) k.setDone(ctx, plan.Name) } diff --git a/x/upgrade/keeper/keeper_test.go b/x/upgrade/keeper/keeper_test.go index 6e91ef3c2372..48f0301d3ff1 100644 --- a/x/upgrade/keeper/keeper_test.go +++ b/x/upgrade/keeper/keeper_test.go @@ -11,10 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" - ibcexported "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -61,18 +57,6 @@ func (s *KeeperTestSuite) TestReadUpgradeInfoFromDisk() { } func (s *KeeperTestSuite) TestScheduleUpgrade() { - clientState := &ibctmtypes.ClientState{ChainId: "gaiachain"} - cs, err := clienttypes.PackClientState(clientState) - s.Require().NoError(err) - - altClientState := &ibctmtypes.ClientState{ChainId: "ethermint"} - altCs, err := clienttypes.PackClientState(altClientState) - s.Require().NoError(err) - - consState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("app_hash")), []byte("next_vals_hash")) - consAny, err := clienttypes.PackConsensusState(consState) - s.Require().NoError(err) - cases := []struct { name string plan types.Plan @@ -99,17 +83,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { setup: func() {}, expPass: true, }, - { - name: "successful ibc schedule", - plan: types.Plan{ - Name: "all-good", - Info: "some text here", - Height: 123450000, - UpgradedClientState: cs, - }, - setup: func() {}, - expPass: true, - }, { name: "successful overwrite", plan: types.Plan{ @@ -126,41 +99,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { }, expPass: true, }, - { - name: "successful IBC overwrite", - plan: types.Plan{ - Name: "all-good", - Info: "some text here", - Height: 123450000, - UpgradedClientState: cs, - }, - setup: func() { - s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, types.Plan{ - Name: "alt-good", - Info: "new text here", - Height: 543210000, - UpgradedClientState: altCs, - }) - }, - expPass: true, - }, - { - name: "successful IBC overwrite with non IBC plan", - plan: types.Plan{ - Name: "all-good", - Info: "some text here", - Height: 123450000, - }, - setup: func() { - s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, types.Plan{ - Name: "alt-good", - Info: "new text here", - Height: 543210000, - UpgradedClientState: altCs, - }) - }, - expPass: true, - }, { name: "unsuccessful schedule: invalid plan", plan: types.Plan{ @@ -206,17 +144,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { }, expPass: false, }, - { - name: "unsuccessful IBC schedule: UpgradedClientState is not valid client state", - plan: types.Plan{ - Name: "all-good", - Info: "some text here", - Height: 123450000, - UpgradedClientState: consAny, - }, - setup: func() {}, - expPass: false, - }, } for _, tc := range cases { @@ -233,16 +160,6 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { if tc.expPass { s.Require().NoError(err, "valid test case failed") - if tc.plan.UpgradedClientState != nil { - got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.plan.Height) - s.Require().NoError(err) - s.Require().Equal(clientState, got, "upgradedClient not equal to expected value") - } else { - // check that upgraded client is empty if latest plan does not specify an upgraded client - got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.plan.Height) - s.Require().Error(err) - s.Require().Nil(got) - } } else { s.Require().Error(err, "invalid test case passed") } @@ -251,9 +168,8 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { } func (s *KeeperTestSuite) TestSetUpgradedClient() { - var ( - clientState ibcexported.ClientState - ) + cs := []byte("IBC client state") + cases := []struct { name string height int64 @@ -270,8 +186,7 @@ func (s *KeeperTestSuite) TestSetUpgradedClient() { name: "success", height: 10, setup: func() { - clientState = &ibctmtypes.ClientState{ChainId: "gaiachain"} - s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, clientState) + s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, cs) }, exists: true, }, @@ -284,13 +199,13 @@ func (s *KeeperTestSuite) TestSetUpgradedClient() { // setup test case tc.setup() - gotCs, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.height) + gotCs, exists := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.height) if tc.exists { - s.Require().Equal(clientState, gotCs, "valid case: %s did not retrieve correct client state", tc.name) - s.Require().NoError(err, "valid case: %s returned error") + s.Require().Equal(cs, gotCs, "valid case: %s did not retrieve correct client state", tc.name) + s.Require().True(exists, "valid case: %s did not retrieve client state", tc.name) } else { s.Require().Nil(gotCs, "invalid case: %s retrieved valid client state", tc.name) - s.Require().Error(err, "invalid case: %s did not return error", tc.name) + s.Require().False(exists, "invalid case: %s retrieved valid client state", tc.name) } } diff --git a/x/upgrade/types/plan.go b/x/upgrade/types/plan.go index aa1a0601ffca..6088ecea15c4 100644 --- a/x/upgrade/types/plan.go +++ b/x/upgrade/types/plan.go @@ -5,30 +5,17 @@ import ( "strings" "time" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - ibcexported "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" ) -var _ codectypes.UnpackInterfacesMessage = Plan{} - func (p Plan) String() string { due := p.DueAt() dueUp := strings.ToUpper(due[0:1]) + due[1:] - var upgradedClientStr string - upgradedClient, err := clienttypes.UnpackClientState(p.UpgradedClientState) - if err != nil { - upgradedClientStr = "no upgraded client provided" - } else { - upgradedClientStr = upgradedClient.String() - } return fmt.Sprintf(`Upgrade Plan Name: %s %s - Info: %s. - Upgraded IBC Client: %s`, p.Name, dueUp, p.Info, upgradedClientStr) + Info: %s.`, p.Name, dueUp, p.Info) } // ValidateBasic does basic validation of a Plan @@ -45,9 +32,6 @@ func (p Plan) ValidateBasic() error { if p.Time.Unix() > 0 && p.Height != 0 { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "cannot set both time and height") } - if p.Time.Unix() > 0 && p.UpgradedClientState != nil { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "IBC chain upgrades must only set height") - } return nil } @@ -70,19 +54,3 @@ func (p Plan) DueAt() string { } return fmt.Sprintf("height: %d", p.Height) } - -// IsIBCPlan will return true if plan includes IBC client information -func (p Plan) IsIBCPlan() bool { - return p.UpgradedClientState != nil -} - -// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces -func (p Plan) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - // UpgradedClientState may be nil - if p.UpgradedClientState == nil { - return nil - } - - var clientState ibcexported.ClientState - return unpacker.UnpackAny(p.UpgradedClientState, &clientState) -} diff --git a/x/upgrade/types/plan_test.go b/x/upgrade/types/plan_test.go index 436cb83a94e3..37f5f5c9abcb 100644 --- a/x/upgrade/types/plan_test.go +++ b/x/upgrade/types/plan_test.go @@ -1,7 +1,6 @@ package types_test import ( - "fmt" "testing" "time" @@ -10,8 +9,6 @@ import ( "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/upgrade/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -26,9 +23,6 @@ func mustParseTime(s string) time.Time { } func TestPlanString(t *testing.T) { - cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) - require.NoError(t, err) - cases := map[string]struct { p types.Plan expect string @@ -39,7 +33,7 @@ func TestPlanString(t *testing.T) { Info: "https://foo.bar", Time: mustParseTime("2019-07-08T11:33:55Z"), }, - expect: "Upgrade Plan\n Name: due_time\n Time: 2019-07-08T11:33:55Z\n Info: https://foo.bar.\n Upgraded IBC Client: no upgraded client provided", + expect: "Upgrade Plan\n Name: due_time\n Time: 2019-07-08T11:33:55Z\n Info: https://foo.bar.", }, "with height": { p: types.Plan{ @@ -47,23 +41,13 @@ func TestPlanString(t *testing.T) { Info: "https://foo.bar/baz", Height: 7890, }, - expect: "Upgrade Plan\n Name: by height\n Height: 7890\n Info: https://foo.bar/baz.\n Upgraded IBC Client: no upgraded client provided", - }, - "with IBC client": { - p: types.Plan{ - Name: "by height", - Info: "https://foo.bar/baz", - Height: 7890, - UpgradedClientState: cs, - }, - expect: fmt.Sprintf("Upgrade Plan\n Name: by height\n Height: 7890\n Info: https://foo.bar/baz.\n Upgraded IBC Client: %s", &ibctmtypes.ClientState{}), + expect: "Upgrade Plan\n Name: by height\n Height: 7890\n Info: https://foo.bar/baz.", }, - "neither": { p: types.Plan{ Name: "almost-empty", }, - expect: "Upgrade Plan\n Name: almost-empty\n Height: 0\n Info: .\n Upgraded IBC Client: no upgraded client provided", + expect: "Upgrade Plan\n Name: almost-empty\n Height: 0\n Info: .", }, } @@ -77,9 +61,6 @@ func TestPlanString(t *testing.T) { } func TestPlanValid(t *testing.T) { - cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) - require.NoError(t, err) - cases := map[string]struct { p types.Plan valid bool @@ -92,15 +73,6 @@ func TestPlanValid(t *testing.T) { }, valid: true, }, - "proper ibc upgrade": { - p: types.Plan{ - Name: "ibc-all-good", - Info: "some text here", - Height: 123450000, - UpgradedClientState: cs, - }, - valid: true, - }, "proper by height": { p: types.Plan{ Name: "all-good", @@ -125,15 +97,6 @@ func TestPlanValid(t *testing.T) { Height: -12345, }, }, - "time due date defined for IBC plan": { - p: types.Plan{ - Name: "ibc-all-good", - Info: "some text here", - Time: mustParseTime("2019-07-08T11:33:55Z"), - UpgradedClientState: cs, - }, - valid: false, - }, } for name, tc := range cases { diff --git a/x/upgrade/types/proposal.go b/x/upgrade/types/proposal.go index a8ea9b629062..38b2295556de 100644 --- a/x/upgrade/types/proposal.go +++ b/x/upgrade/types/proposal.go @@ -3,7 +3,6 @@ package types import ( "fmt" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" gov "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -18,7 +17,6 @@ func NewSoftwareUpgradeProposal(title, description string, plan Plan) gov.Conten // Implements Proposal Interface var _ gov.Content = &SoftwareUpgradeProposal{} -var _ codectypes.UnpackInterfacesMessage = SoftwareUpgradeProposal{} func init() { gov.RegisterProposalType(ProposalTypeSoftwareUpgrade) @@ -45,11 +43,6 @@ func (sup SoftwareUpgradeProposal) String() string { `, sup.Title, sup.Description) } -// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces -func (sup SoftwareUpgradeProposal) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - return sup.Plan.UnpackInterfaces(unpacker) -} - func NewCancelSoftwareUpgradeProposal(title, description string) gov.Content { return &CancelSoftwareUpgradeProposal{title, description} } diff --git a/x/upgrade/types/proposal_test.go b/x/upgrade/types/proposal_test.go index d39b89135c3d..4f5ed16a82fa 100644 --- a/x/upgrade/types/proposal_test.go +++ b/x/upgrade/types/proposal_test.go @@ -9,8 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" gov "github.com/cosmos/cosmos-sdk/x/gov/types" - clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" - ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -79,17 +77,12 @@ func TestContentAccessors(t *testing.T) { } } -// tests a software update proposal can be marshaled and unmarshaled, and the -// client state can be unpacked +// tests a software update proposal can be marshaled and unmarshaled func TestMarshalSoftwareUpdateProposal(t *testing.T) { - cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) - require.NoError(t, err) - // create proposal plan := types.Plan{ - Name: "upgrade ibc", - Height: 1000, - UpgradedClientState: cs, + Name: "upgrade", + Height: 1000, } content := types.NewSoftwareUpgradeProposal("title", "description", plan) sup, ok := content.(*types.SoftwareUpgradeProposal) @@ -98,9 +91,7 @@ func TestMarshalSoftwareUpdateProposal(t *testing.T) { // create codec ir := codectypes.NewInterfaceRegistry() types.RegisterInterfaces(ir) - clienttypes.RegisterInterfaces(ir) gov.RegisterInterfaces(ir) - ibctmtypes.RegisterInterfaces(ir) cdc := codec.NewProtoCodec(ir) // marshal message @@ -111,8 +102,4 @@ func TestMarshalSoftwareUpdateProposal(t *testing.T) { newSup := &types.SoftwareUpgradeProposal{} err = cdc.UnmarshalJSON(bz, newSup) require.NoError(t, err) - - // unpack client state - _, err = clienttypes.UnpackClientState(newSup.Plan.UpgradedClientState) - require.NoError(t, err) } diff --git a/x/upgrade/types/query.pb.go b/x/upgrade/types/query.pb.go index 40caf74e8f6d..936ad03b7055 100644 --- a/x/upgrade/types/query.pb.go +++ b/x/upgrade/types/query.pb.go @@ -6,7 +6,7 @@ package types import ( context "context" fmt "fmt" - types "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/cosmos-sdk/codec/types" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -259,7 +259,7 @@ func (m *QueryUpgradedConsensusStateRequest) GetLastHeight() int64 { // QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState // RPC method. type QueryUpgradedConsensusStateResponse struct { - UpgradedConsensusState *types.Any `protobuf:"bytes,1,opt,name=upgraded_consensus_state,json=upgradedConsensusState,proto3" json:"upgraded_consensus_state,omitempty"` + UpgradedConsensusState []byte `protobuf:"bytes,2,opt,name=upgraded_consensus_state,json=upgradedConsensusState,proto3" json:"upgraded_consensus_state,omitempty"` } func (m *QueryUpgradedConsensusStateResponse) Reset() { *m = QueryUpgradedConsensusStateResponse{} } @@ -295,7 +295,7 @@ func (m *QueryUpgradedConsensusStateResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryUpgradedConsensusStateResponse proto.InternalMessageInfo -func (m *QueryUpgradedConsensusStateResponse) GetUpgradedConsensusState() *types.Any { +func (m *QueryUpgradedConsensusStateResponse) GetUpgradedConsensusState() []byte { if m != nil { return m.UpgradedConsensusState } @@ -316,38 +316,38 @@ func init() { } var fileDescriptor_4a334d07ad8374f0 = []byte{ - // 487 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x8b, 0x13, 0x31, - 0x18, 0x6d, 0xb4, 0x2e, 0x98, 0xde, 0x82, 0xd4, 0x6e, 0x59, 0x46, 0x89, 0x8b, 0x08, 0x6e, 0x93, - 0xdd, 0xee, 0x4d, 0x41, 0x5c, 0x17, 0x17, 0x0f, 0x22, 0x5a, 0xf1, 0xe2, 0xa5, 0xa4, 0x9d, 0x38, - 0x1d, 0x9c, 0x26, 0xd9, 0x49, 0x22, 0x96, 0x65, 0x2f, 0xfe, 0x02, 0xc1, 0xbb, 0x37, 0x6f, 0xfe, - 0x10, 0x8f, 0x0b, 0x5e, 0xf4, 0x26, 0xad, 0x3f, 0x44, 0x26, 0xc9, 0x48, 0x97, 0x76, 0x66, 0xc5, - 0x53, 0x3b, 0x93, 0xf7, 0xbe, 0xf7, 0xbe, 0xbc, 0x37, 0x10, 0x8f, 0xa5, 0x9e, 0x4a, 0x4d, 0xad, - 0x4a, 0x72, 0x16, 0x73, 0xfa, 0x6e, 0x6f, 0xc4, 0x0d, 0xdb, 0xa3, 0xc7, 0x96, 0xe7, 0x33, 0xa2, - 0x72, 0x69, 0x24, 0x6a, 0x7b, 0x0c, 0x09, 0x18, 0x12, 0x30, 0xdd, 0xcd, 0x44, 0xca, 0x24, 0xe3, - 0xd4, 0xa1, 0x46, 0xf6, 0x0d, 0x65, 0x22, 0x50, 0xba, 0x5b, 0xe1, 0x88, 0xa9, 0x94, 0x32, 0x21, - 0xa4, 0x61, 0x26, 0x95, 0x42, 0x87, 0xd3, 0xed, 0x0a, 0xd1, 0x52, 0xc0, 0xa1, 0xf0, 0x26, 0xbc, - 0xfe, 0xa2, 0x70, 0x71, 0x68, 0xf3, 0x9c, 0x0b, 0xf3, 0x3c, 0x63, 0x62, 0xc0, 0x8f, 0x2d, 0xd7, - 0x06, 0x3f, 0x85, 0x9d, 0xd5, 0x23, 0xad, 0xa4, 0xd0, 0x1c, 0xed, 0xc2, 0xa6, 0xca, 0x98, 0xe8, - 0x80, 0x9b, 0xe0, 0x4e, 0xab, 0xbf, 0x45, 0xd6, 0x9b, 0x27, 0x8e, 0xe3, 0x90, 0xb8, 0x17, 0x84, - 0x0e, 0x94, 0xca, 0x52, 0x1e, 0x2f, 0x09, 0x21, 0x04, 0x9b, 0x82, 0x4d, 0xb9, 0x1b, 0x76, 0x75, - 0xe0, 0xfe, 0xe3, 0x7e, 0x10, 0x3f, 0x07, 0x0f, 0xe2, 0x6d, 0xb8, 0x31, 0xe1, 0x69, 0x32, 0x31, - 0x8e, 0x71, 0x79, 0x10, 0x9e, 0xf0, 0x63, 0x88, 0x1d, 0xe7, 0x95, 0x77, 0x11, 0x1f, 0x16, 0x68, - 0xa1, 0xad, 0x7e, 0x69, 0x98, 0xe1, 0xa5, 0xda, 0x0d, 0xd8, 0xca, 0x98, 0x36, 0xc3, 0x73, 0x23, - 0x60, 0xf1, 0xea, 0x89, 0x1f, 0x63, 0xe1, 0xad, 0xda, 0x31, 0xc1, 0xc5, 0x33, 0xd8, 0x09, 0xeb, - 0xc6, 0xc3, 0x71, 0x09, 0x19, 0xea, 0x02, 0x13, 0xae, 0xe5, 0x1a, 0xf1, 0x01, 0x91, 0x32, 0x3b, - 0x72, 0x20, 0x66, 0x83, 0xb6, 0x5d, 0x3b, 0xb7, 0xff, 0xb5, 0x09, 0xaf, 0x38, 0x5d, 0xf4, 0x19, - 0xc0, 0xd6, 0xd2, 0xa5, 0x23, 0x5a, 0x75, 0xbd, 0x15, 0xc9, 0x75, 0x77, 0xff, 0x9d, 0xe0, 0x97, - 0xc1, 0x3b, 0x1f, 0xbe, 0xff, 0xfe, 0x74, 0xe9, 0x36, 0xda, 0xa6, 0x15, 0xad, 0x19, 0x7b, 0xd2, - 0xb0, 0xc8, 0x12, 0x7d, 0x01, 0xb0, 0xb5, 0x14, 0xcc, 0x05, 0x06, 0x57, 0x13, 0xbf, 0xc0, 0xe0, - 0x9a, 0xcc, 0xf1, 0xbe, 0x33, 0xd8, 0x43, 0x77, 0xab, 0x0c, 0x32, 0x4f, 0x72, 0x06, 0xe9, 0x49, - 0xd1, 0xa1, 0x53, 0xf4, 0x13, 0xc0, 0xf6, 0xfa, 0x14, 0xd1, 0xbd, 0x5a, 0x07, 0xb5, 0x0d, 0xea, - 0xde, 0xff, 0x2f, 0x6e, 0x58, 0xe4, 0xc8, 0x2d, 0xf2, 0x10, 0x3d, 0xa0, 0xf5, 0xdf, 0xe7, 0x4a, - 0xa9, 0xe8, 0xc9, 0x52, 0x6d, 0x4f, 0x1f, 0x1d, 0x7d, 0x9b, 0x47, 0xe0, 0x6c, 0x1e, 0x81, 0x5f, - 0xf3, 0x08, 0x7c, 0x5c, 0x44, 0x8d, 0xb3, 0x45, 0xd4, 0xf8, 0xb1, 0x88, 0x1a, 0xaf, 0x77, 0x92, - 0xd4, 0x4c, 0xec, 0x88, 0x8c, 0xe5, 0xb4, 0xd4, 0xf0, 0x3f, 0x3d, 0x1d, 0xbf, 0xa5, 0xef, 0xff, - 0x0a, 0x9a, 0x99, 0xe2, 0x7a, 0xb4, 0xe1, 0xca, 0xb9, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, 0xee, - 0x4b, 0xe2, 0xe8, 0xa4, 0x04, 0x00, 0x00, + // 490 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcf, 0x6b, 0x13, 0x41, + 0x18, 0xcd, 0xc4, 0x58, 0x74, 0xe2, 0x41, 0xe6, 0x10, 0xd3, 0x50, 0xd6, 0x32, 0x16, 0x29, 0xd8, + 0xec, 0xb4, 0xe9, 0x45, 0x14, 0x44, 0x2d, 0x16, 0x11, 0x0f, 0x1a, 0xf1, 0xe2, 0x25, 0x4c, 0xb2, + 0xe3, 0x66, 0x71, 0x33, 0x33, 0xdd, 0x99, 0x11, 0x4b, 0xe9, 0xc5, 0xbf, 0x40, 0xf0, 0xee, 0xcd, + 0x9b, 0x7f, 0x88, 0xc7, 0x82, 0x17, 0xbd, 0x49, 0xe2, 0x1f, 0x22, 0x3b, 0x3b, 0x2b, 0x5b, 0xb2, + 0xbb, 0x91, 0x9e, 0xf6, 0xc7, 0xf7, 0xde, 0xf7, 0xde, 0x37, 0xef, 0x1b, 0x88, 0x27, 0x42, 0xcd, + 0x84, 0x22, 0x46, 0x86, 0x09, 0x0d, 0x18, 0x79, 0xbf, 0x37, 0x66, 0x9a, 0xee, 0x91, 0x23, 0xc3, + 0x92, 0x63, 0x5f, 0x26, 0x42, 0x0b, 0xd4, 0xc9, 0x30, 0xbe, 0xc3, 0xf8, 0x0e, 0xd3, 0x5b, 0x0f, + 0x85, 0x08, 0x63, 0x46, 0x2c, 0x6a, 0x6c, 0xde, 0x12, 0xca, 0x1d, 0xa5, 0xb7, 0xe1, 0x4a, 0x54, + 0x46, 0x84, 0x72, 0x2e, 0x34, 0xd5, 0x91, 0xe0, 0xca, 0x55, 0xb7, 0x2a, 0x44, 0x73, 0x01, 0x8b, + 0xc2, 0xeb, 0xf0, 0xc6, 0xcb, 0xd4, 0xc5, 0x81, 0x49, 0x12, 0xc6, 0xf5, 0x8b, 0x98, 0xf2, 0x21, + 0x3b, 0x32, 0x4c, 0x69, 0xfc, 0x1c, 0x76, 0x97, 0x4b, 0x4a, 0x0a, 0xae, 0x18, 0xda, 0x85, 0x2d, + 0x19, 0x53, 0xde, 0x05, 0x9b, 0x60, 0xbb, 0x3d, 0xd8, 0xf0, 0xcb, 0xcd, 0xfb, 0x96, 0x63, 0x91, + 0xb8, 0xef, 0x84, 0x1e, 0x49, 0x19, 0x47, 0x2c, 0x28, 0x08, 0x21, 0x04, 0x5b, 0x9c, 0xce, 0x98, + 0x6d, 0x76, 0x75, 0x68, 0xdf, 0xf1, 0xc0, 0x89, 0x9f, 0x83, 0x3b, 0xf1, 0x0e, 0x5c, 0x9b, 0xb2, + 0x28, 0x9c, 0x6a, 0xcb, 0xb8, 0x34, 0x74, 0x5f, 0xf8, 0x09, 0xc4, 0x96, 0xf3, 0x3a, 0x73, 0x11, + 0x1c, 0xa4, 0x68, 0xae, 0x8c, 0x7a, 0xa5, 0xa9, 0x66, 0xb9, 0xda, 0x4d, 0xd8, 0x8e, 0xa9, 0xd2, + 0xa3, 0x73, 0x2d, 0x60, 0xfa, 0xeb, 0x69, 0xd6, 0x86, 0xc1, 0x5b, 0xb5, 0x6d, 0x9c, 0x8b, 0xbb, + 0xb0, 0xeb, 0xc6, 0x0d, 0x46, 0x93, 0x1c, 0x32, 0x52, 0x29, 0xa6, 0xdb, 0xdc, 0x04, 0xdb, 0xd7, + 0x86, 0x1d, 0x53, 0xda, 0xe1, 0x59, 0xeb, 0x0a, 0xb8, 0xde, 0x1c, 0x7c, 0x6b, 0xc1, 0xcb, 0x56, + 0x07, 0x7d, 0x01, 0xb0, 0x5d, 0x38, 0x64, 0x44, 0xaa, 0x8e, 0xb3, 0x22, 0xa9, 0xde, 0xee, 0xff, + 0x13, 0x32, 0xf3, 0x78, 0xe7, 0xe3, 0x8f, 0x3f, 0x9f, 0x9b, 0xb7, 0xd1, 0x16, 0xa9, 0xd8, 0x92, + 0x49, 0x46, 0x1a, 0xa5, 0xd9, 0xa1, 0xaf, 0x00, 0xb6, 0x0b, 0x41, 0xac, 0x30, 0xb8, 0x9c, 0xf0, + 0x0a, 0x83, 0x25, 0x19, 0xe3, 0x7d, 0x6b, 0xb0, 0x8f, 0xee, 0x54, 0x19, 0xa4, 0x19, 0xc9, 0x1a, + 0x24, 0x27, 0xe9, 0xce, 0x9c, 0xa2, 0x5f, 0x00, 0x76, 0xca, 0x53, 0x43, 0xf7, 0x6a, 0x1d, 0xd4, + 0x6e, 0x4c, 0xef, 0xfe, 0x85, 0xb8, 0x6e, 0x90, 0x43, 0x3b, 0xc8, 0x43, 0xf4, 0x80, 0xd4, 0xdf, + 0xc7, 0xa5, 0x25, 0x22, 0x27, 0x85, 0x35, 0x3d, 0x7d, 0x7c, 0xf8, 0x7d, 0xee, 0x81, 0xb3, 0xb9, + 0x07, 0x7e, 0xcf, 0x3d, 0xf0, 0x69, 0xe1, 0x35, 0xce, 0x16, 0x5e, 0xe3, 0xe7, 0xc2, 0x6b, 0xbc, + 0xd9, 0x09, 0x23, 0x3d, 0x35, 0x63, 0x7f, 0x22, 0x66, 0xb9, 0x46, 0xf6, 0xe8, 0xab, 0xe0, 0x1d, + 0xf9, 0xf0, 0x4f, 0x50, 0x1f, 0x4b, 0xa6, 0xc6, 0x6b, 0xf6, 0xde, 0xef, 0xff, 0x0d, 0x00, 0x00, + 0xff, 0xff, 0x32, 0x81, 0xe9, 0x7a, 0x94, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -678,17 +678,12 @@ func (m *QueryUpgradedConsensusStateResponse) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l - if m.UpgradedConsensusState != nil { - { - size, err := m.UpgradedConsensusState.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } + if len(m.UpgradedConsensusState) > 0 { + i -= len(m.UpgradedConsensusState) + copy(dAtA[i:], m.UpgradedConsensusState) + i = encodeVarintQuery(dAtA, i, uint64(len(m.UpgradedConsensusState))) i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 } return len(dAtA) - i, nil } @@ -769,8 +764,8 @@ func (m *QueryUpgradedConsensusStateResponse) Size() (n int) { } var l int _ = l - if m.UpgradedConsensusState != nil { - l = m.UpgradedConsensusState.Size() + l = len(m.UpgradedConsensusState) + if l > 0 { n += 1 + l + sovQuery(uint64(l)) } return n @@ -1167,11 +1162,11 @@ func (m *QueryUpgradedConsensusStateResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: QueryUpgradedConsensusStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UpgradedConsensusState", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -1181,26 +1176,24 @@ func (m *QueryUpgradedConsensusStateResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } + m.UpgradedConsensusState = append(m.UpgradedConsensusState[:0], dAtA[iNdEx:postIndex]...) if m.UpgradedConsensusState == nil { - m.UpgradedConsensusState = &types.Any{} - } - if err := m.UpgradedConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.UpgradedConsensusState = []byte{} } iNdEx = postIndex default: diff --git a/x/upgrade/types/upgrade.pb.go b/x/upgrade/types/upgrade.pb.go index 642f4446fe28..c77d90f34df8 100644 --- a/x/upgrade/types/upgrade.pb.go +++ b/x/upgrade/types/upgrade.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - types "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" @@ -47,12 +47,6 @@ type Plan struct { // Any application specific upgrade info to be included on-chain // such as a git commit that validators could automatically upgrade to Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"` - // IBC-enabled chains can opt-in to including the upgraded client state in its upgrade plan - // This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, - // so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the - // previous version of the chain. - // This will allow IBC connections to persist smoothly across planned chain upgrades - UpgradedClientState *types.Any `protobuf:"bytes,5,opt,name=upgraded_client_state,json=upgradedClientState,proto3" json:"upgraded_client_state,omitempty" yaml:"upgraded_client_state"` } func (m *Plan) Reset() { *m = Plan{} } @@ -177,34 +171,32 @@ func init() { } var fileDescriptor_ccf2a7d4d7b48dca = []byte{ - // 426 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x52, 0x31, 0x6f, 0xd4, 0x30, - 0x18, 0x8d, 0x69, 0x5a, 0x51, 0xdf, 0x66, 0x8e, 0x12, 0x4e, 0xc5, 0x89, 0x4e, 0x0c, 0x37, 0x80, - 0xa3, 0x16, 0x09, 0xa1, 0x6e, 0xa4, 0x3b, 0xaa, 0x52, 0x58, 0x90, 0x50, 0xe5, 0x24, 0xbe, 0x9c, - 0xc1, 0xb1, 0xa3, 0xd8, 0x07, 0xe4, 0x57, 0xd0, 0x9f, 0xc0, 0xcf, 0xb9, 0xb1, 0x63, 0xa7, 0x42, - 0xef, 0x16, 0xe6, 0xfe, 0x02, 0x14, 0x3b, 0x41, 0x08, 0x3a, 0x76, 0xf2, 0xf7, 0x3d, 0xbd, 0xef, - 0x3d, 0xfb, 0xf9, 0x83, 0x4f, 0x73, 0xa5, 0x2b, 0xa5, 0xe3, 0x65, 0x5d, 0x36, 0xb4, 0x60, 0xf1, - 0xe7, 0x83, 0x8c, 0x19, 0x7a, 0x30, 0xf4, 0xa4, 0x6e, 0x94, 0x51, 0x68, 0xcf, 0xb1, 0xc8, 0x80, - 0xf6, 0xac, 0xc9, 0xe3, 0x52, 0xa9, 0x52, 0xb0, 0xd8, 0xb2, 0xb2, 0xe5, 0x3c, 0xa6, 0xb2, 0x75, - 0x23, 0x93, 0x71, 0xa9, 0x4a, 0x65, 0xcb, 0xb8, 0xab, 0x7a, 0x34, 0xfc, 0x77, 0xc0, 0xf0, 0x8a, - 0x69, 0x43, 0xab, 0xda, 0x11, 0xa6, 0x37, 0x00, 0xfa, 0x27, 0x82, 0x4a, 0x84, 0xa0, 0x2f, 0x69, - 0xc5, 0x02, 0x10, 0x81, 0xd9, 0x6e, 0x6a, 0x6b, 0xf4, 0x0a, 0xfa, 0x1d, 0x3f, 0xb8, 0x17, 0x81, - 0xd9, 0xe8, 0x70, 0x42, 0x9c, 0x18, 0x19, 0xc4, 0xc8, 0xdb, 0x41, 0x2c, 0xb9, 0xbf, 0xba, 0x0a, - 0xbd, 0xf3, 0x1f, 0x21, 0x48, 0xed, 0x04, 0xda, 0x83, 0x3b, 0x0b, 0xc6, 0xcb, 0x85, 0x09, 0xb6, - 0x22, 0x30, 0xdb, 0x4a, 0xfb, 0xae, 0x73, 0xe1, 0x72, 0xae, 0x02, 0xdf, 0xb9, 0x74, 0x35, 0xfa, - 0x08, 0x1f, 0xf6, 0xef, 0x2c, 0xce, 0x72, 0xc1, 0x99, 0x34, 0x67, 0xda, 0x50, 0xc3, 0x82, 0x6d, - 0x6b, 0x3b, 0xfe, 0xcf, 0xf6, 0xb5, 0x6c, 0x93, 0xe8, 0xe6, 0x2a, 0xdc, 0x6f, 0x69, 0x25, 0x8e, - 0xa6, 0xb7, 0x0e, 0x4f, 0xd3, 0x07, 0x03, 0x7e, 0x6c, 0xe1, 0xd3, 0x0e, 0x3d, 0xf2, 0x7f, 0x7d, - 0x0f, 0xc1, 0xf4, 0x1b, 0x80, 0x8f, 0x4e, 0xd5, 0xdc, 0x7c, 0xa1, 0x0d, 0x7b, 0xe7, 0x58, 0x27, - 0x8d, 0xaa, 0x95, 0xa6, 0x02, 0x8d, 0xe1, 0xb6, 0xe1, 0x46, 0x0c, 0x41, 0xb8, 0x06, 0x45, 0x70, - 0x54, 0x30, 0x9d, 0x37, 0xbc, 0x36, 0x5c, 0x49, 0x1b, 0xc8, 0x6e, 0xfa, 0x37, 0x84, 0x5e, 0x42, - 0xbf, 0x16, 0x54, 0xda, 0xf7, 0x8e, 0x0e, 0xf7, 0xc9, 0xed, 0x3f, 0x48, 0xba, 0xac, 0x13, 0xbf, - 0x4b, 0x2b, 0xb5, 0xfc, 0xfe, 0x46, 0x1f, 0xe0, 0x93, 0x63, 0x2a, 0x73, 0x26, 0xee, 0xf8, 0x5a, - 0x4e, 0x3e, 0x79, 0xb3, 0xba, 0xc6, 0xde, 0xe5, 0x35, 0xf6, 0x56, 0x6b, 0x0c, 0x2e, 0xd6, 0x18, - 0xfc, 0x5c, 0x63, 0x70, 0xbe, 0xc1, 0xde, 0xc5, 0x06, 0x7b, 0x97, 0x1b, 0xec, 0xbd, 0x7f, 0x56, - 0x72, 0xb3, 0x58, 0x66, 0x24, 0x57, 0x55, 0xdc, 0xaf, 0xa8, 0x3b, 0x9e, 0xeb, 0xe2, 0x53, 0xfc, - 0xf5, 0xcf, 0xbe, 0x9a, 0xb6, 0x66, 0x3a, 0xdb, 0xb1, 0x7f, 0xf1, 0xe2, 0x77, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xca, 0x9e, 0x7a, 0x5d, 0xce, 0x02, 0x00, 0x00, + // 391 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x52, 0xb1, 0x6e, 0xdb, 0x30, + 0x10, 0x15, 0x6b, 0x5a, 0xb0, 0xe9, 0xa5, 0x20, 0x0c, 0x57, 0x35, 0x5a, 0x4a, 0x30, 0x3a, 0x78, + 0x68, 0x29, 0xd8, 0x05, 0x8a, 0xa2, 0xa3, 0xbb, 0x75, 0x28, 0x0c, 0xb5, 0x5d, 0x0a, 0x64, 0xa0, + 0x64, 0x5a, 0x16, 0x22, 0x89, 0x82, 0x44, 0x27, 0xf1, 0x57, 0xc4, 0x43, 0x3e, 0x20, 0x9f, 0xe3, + 0xd1, 0xa3, 0xa7, 0x24, 0xb6, 0x97, 0x7c, 0x46, 0x20, 0x52, 0x0a, 0x82, 0x20, 0x63, 0x26, 0xbd, + 0x3b, 0xbc, 0x7b, 0xf7, 0xf4, 0x78, 0xe8, 0x53, 0x20, 0x8a, 0x44, 0x14, 0xee, 0x32, 0x0b, 0x73, + 0x36, 0xe3, 0xee, 0xd9, 0xc8, 0xe7, 0x92, 0x8d, 0xea, 0x9a, 0x66, 0xb9, 0x90, 0x02, 0xf7, 0x34, + 0x8b, 0xd6, 0xdd, 0x8a, 0xd5, 0x7f, 0x1f, 0x0a, 0x11, 0xc6, 0xdc, 0x55, 0x2c, 0x7f, 0x39, 0x77, + 0x59, 0xba, 0xd2, 0x23, 0xfd, 0x6e, 0x28, 0x42, 0xa1, 0xa0, 0x5b, 0xa2, 0xaa, 0x6b, 0x3f, 0x1f, + 0x90, 0x51, 0xc2, 0x0b, 0xc9, 0x92, 0x4c, 0x13, 0x06, 0x57, 0x00, 0xc1, 0x69, 0xcc, 0x52, 0x8c, + 0x11, 0x4c, 0x59, 0xc2, 0x2d, 0xe0, 0x80, 0x61, 0xdb, 0x53, 0x18, 0x7f, 0x47, 0xb0, 0xe4, 0x5b, + 0x6f, 0x1c, 0x30, 0xec, 0x8c, 0xfb, 0x54, 0x8b, 0xd1, 0x5a, 0x8c, 0xfe, 0xad, 0xc5, 0x26, 0xad, + 0xcd, 0x8d, 0x6d, 0xac, 0x6f, 0x6d, 0xe0, 0xa9, 0x09, 0xdc, 0x43, 0xe6, 0x82, 0x47, 0xe1, 0x42, + 0x5a, 0x0d, 0x07, 0x0c, 0x1b, 0x5e, 0x55, 0x95, 0x5b, 0xa2, 0x74, 0x2e, 0x2c, 0xa8, 0xb7, 0x94, + 0xf8, 0x07, 0xbc, 0xbf, 0xb6, 0xc1, 0x2f, 0xd8, 0x6a, 0xbe, 0x35, 0x3d, 0x53, 0x64, 0x32, 0x12, + 0xe9, 0xe0, 0x12, 0xa0, 0x77, 0x7f, 0xc4, 0x5c, 0x9e, 0xb3, 0x9c, 0xff, 0xd3, 0x21, 0x4c, 0x73, + 0x91, 0x89, 0x82, 0xc5, 0xb8, 0x8b, 0x9a, 0x32, 0x92, 0x71, 0x6d, 0x55, 0x17, 0xd8, 0x41, 0x9d, + 0x19, 0x2f, 0x82, 0x3c, 0x52, 0x02, 0xca, 0x72, 0xdb, 0x7b, 0xda, 0xc2, 0xdf, 0x10, 0xcc, 0x62, + 0x96, 0x2a, 0x47, 0x9d, 0xf1, 0x07, 0xfa, 0x72, 0xc6, 0xb4, 0x4c, 0x63, 0x02, 0xcb, 0xff, 0xf1, + 0x14, 0x5f, 0xfb, 0x1b, 0x9c, 0xa0, 0x8f, 0x3f, 0x59, 0x1a, 0xf0, 0xf8, 0x95, 0x6d, 0x69, 0xf9, + 0xc9, 0xef, 0xcd, 0x9e, 0x18, 0xbb, 0x3d, 0x31, 0x36, 0x07, 0x02, 0xb6, 0x07, 0x02, 0xee, 0x0e, + 0x04, 0xac, 0x8f, 0xc4, 0xd8, 0x1e, 0x89, 0xb1, 0x3b, 0x12, 0xe3, 0xff, 0xe7, 0x30, 0x92, 0x8b, + 0xa5, 0x4f, 0x03, 0x91, 0xb8, 0xd5, 0x11, 0xe9, 0xcf, 0x97, 0x62, 0x76, 0xea, 0x5e, 0x3c, 0x5e, + 0x94, 0x5c, 0x65, 0xbc, 0xf0, 0x4d, 0xf5, 0x48, 0x5f, 0x1f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9b, + 0x57, 0x9e, 0x92, 0x70, 0x02, 0x00, 0x00, } func (this *Plan) Equal(that interface{}) bool { @@ -238,9 +230,6 @@ func (this *Plan) Equal(that interface{}) bool { if this.Info != that1.Info { return false } - if !this.UpgradedClientState.Equal(that1.UpgradedClientState) { - return false - } return true } func (this *SoftwareUpgradeProposal) Equal(that interface{}) bool { @@ -320,18 +309,6 @@ func (m *Plan) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.UpgradedClientState != nil { - { - size, err := m.UpgradedClientState.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintUpgrade(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } if len(m.Info) > 0 { i -= len(m.Info) copy(dAtA[i:], m.Info) @@ -344,12 +321,12 @@ func (m *Plan) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err2 != nil { - return 0, err2 + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err1 != nil { + return 0, err1 } - i -= n2 - i = encodeVarintUpgrade(dAtA, i, uint64(n2)) + i -= n1 + i = encodeVarintUpgrade(dAtA, i, uint64(n1)) i-- dAtA[i] = 0x12 if len(m.Name) > 0 { @@ -476,10 +453,6 @@ func (m *Plan) Size() (n int) { if l > 0 { n += 1 + l + sovUpgrade(uint64(l)) } - if m.UpgradedClientState != nil { - l = m.UpgradedClientState.Size() - n += 1 + l + sovUpgrade(uint64(l)) - } return n } @@ -670,42 +643,6 @@ func (m *Plan) Unmarshal(dAtA []byte) error { } m.Info = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpgradedClientState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowUpgrade - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthUpgrade - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthUpgrade - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.UpgradedClientState == nil { - m.UpgradedClientState = &types.Any{} - } - if err := m.UpgradedClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipUpgrade(dAtA[iNdEx:])