ibc: upgrade client (#7367)

* implement upgrade module changes

* implement client changes

* implement core tendermint logic

* remove assumption that new client state has same structure as old

* fix light client builds

* fix rest of build

* fix tendermint tests

* fix all tests except MarshalJSON

* fix, marshalUpgrade fails

* Apply suggestions from code review

* minor updates

* update proto and validate path

* fix MarshalJSON panic

* hack my way to first passing test case

* add rest of upgrade test cases

* fix plan tests

* add keeper tests

* fix upgrade tests

* add more tests

* add upgrade path validation to ValidateSelfClient

* validate upgradedClient

* fix upgrade handler tests

* appease linter

* Apply suggestions from code review

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* change signer to string in proto

* lint

* start address @colin-axner review

* improve test coverage

* fix abci stringer test

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
This commit is contained in:
Aditya 2020-10-01 02:21:57 -04:00 committed by GitHub
parent 1e95292e0d
commit 01fd22d244
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 2768 additions and 932 deletions

1
.gitignore vendored
View File

@ -19,6 +19,7 @@ docs/modules
dist
tools-stamp
proto-tools-stamp
buf-stamp
artifacts
# Data - ideally these don't exist

View File

@ -1,6 +1,7 @@
syntax = "proto3";
package cosmos.upgrade.v1beta1;
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
@ -32,6 +33,13 @@ message Plan {
// Any application specific upgrade info to be included on-chain
// 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\""];;
}
// SoftwareUpgradeProposal is a gov Content type for initiating a software

View File

@ -78,6 +78,18 @@ message MsgUpdateClient {
string signer = 3;
}
// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state
message MsgUpgradeClient {
// client unique identifier
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
// upgraded client state
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
// proof that old chain committed to new client
bytes proof_upgrade = 3 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""];
// signer address
string signer = 4;
}
// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for
// light client misbehaviour.
message MsgSubmitMisbehaviour {

View File

@ -49,13 +49,12 @@ message KeyPath {
message Key {
option (gogoproto.goproto_getters) = false;
bytes name = 1 [(gogoproto.customname) = "name"];
KeyEncoding enc = 2 [(gogoproto.customname) = "enc"];
bytes name = 1;
KeyEncoding enc = 2;
}
// KeyEncoding defines the encoding format of a key's bytes.
enum KeyEncoding {
option (gogoproto.goproto_enum_stringer) = false;
option (gogoproto.goproto_enum_prefix) = false;
// URL encoding

View File

@ -39,12 +39,15 @@ message ClientState {
// Proof specifications used in verifying counterparty state
repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""];
// Path at which next upgraded client will be committed
ibc.commitment.MerklePath upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""];
// This flag, when set to true, will allow governance to recover a client
// which has expired
bool allow_update_after_expiry = 9 [(gogoproto.moretags) = "yaml:\"allow_update_after_expiry\""];
bool allow_update_after_expiry = 10 [(gogoproto.moretags) = "yaml:\"allow_update_after_expiry\""];
// This flag, when set to true, will allow governance to unfreeze a client
// whose chain has experienced a misbehaviour event
bool allow_update_after_misbehaviour = 10 [(gogoproto.moretags) = "yaml:\"allow_update_after_misbehaviour\""];
bool allow_update_after_misbehaviour = 11 [(gogoproto.moretags) = "yaml:\"allow_update_after_misbehaviour\""];
}
// ConsensusState defines the consensus state from Tendermint.

View File

@ -65,6 +65,33 @@ func HandleMsgUpdateClient(ctx sdk.Context, k keeper.Keeper, msg *types.MsgUpdat
}, nil
}
// HandleMsgUpgradeClient defines the sdk.Handler for MsgUpgradeClient
func HandleMsgUpgradeClient(ctx sdk.Context, k keeper.Keeper, msg *types.MsgUpgradeClient) (*sdk.Result, error) {
upgradedClient, err := types.UnpackClientState(msg.ClientState)
if err != nil {
return nil, err
}
if err := upgradedClient.Validate(); err != nil {
return nil, err
}
if err = k.UpgradeClient(ctx, msg.ClientId, upgradedClient, msg.ProofUpgrade); err != nil {
return nil, err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
),
)
return &sdk.Result{
Events: ctx.EventManager().Events().ToABCIEvents(),
}, nil
}
// HandleMsgSubmitMisbehaviour defines the Evidence module handler for submitting a
// light client misbehaviour.
func HandleMsgSubmitMisbehaviour(ctx sdk.Context, k keeper.Keeper, msg *types.MsgSubmitMisbehaviour) (*sdk.Result, error) {

View File

@ -1,13 +1,20 @@
package client_test
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
client "github.com/cosmos/cosmos-sdk/x/ibc/02-client"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/ibc/exported"
solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/solomachine/types"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
func (suite *ClientTestSuite) TestNewClientUpdateProposalHandler() {
@ -73,3 +80,152 @@ func (suite *ClientTestSuite) TestNewClientUpdateProposalHandler() {
}
}
func (suite *ClientTestSuite) TestUpgradeClient() {
var (
clientA string
upgradedClient exported.ClientState
msg *clienttypes.MsgUpgradeClient
)
upgradeHeight := clienttypes.NewHeight(1, 1)
cases := []struct {
name string
setup func()
expPass bool
}{
{
name: "successful upgrade",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, proofUpgrade, suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
expPass: true,
},
{
name: "successful upgrade to different client type",
setup: func() {
// previous chain committed to the change
upgradedClient = ibctesting.NewSolomachine(suite.T(), suite.chainA.App.AppCodec(), clientA, "diversifier", 1).ClientState()
soloClient, _ := upgradedClient.(*solomachinetypes.ClientState)
// change sequence to be higher height than latest current client height
soloClient.Sequence = 100000000000
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), soloClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, proofUpgrade, suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
expPass: true,
},
{
name: "invalid upgrade: msg.ClientState does not contain valid clientstate",
setup: func() {
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
consState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("app_hash")), []byte("next_vals_hash"))
consAny, err := clienttypes.PackConsensusState(consState)
suite.Require().NoError(err)
msg = &types.MsgUpgradeClient{ClientId: clientA, ClientState: consAny, ProofUpgrade: proofUpgrade, Signer: suite.chainA.SenderAccount.GetAddress().String()}
},
expPass: false,
},
{
name: "invalid clientstate",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, proofUpgrade, suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
expPass: false,
},
{
name: "VerifyUpgrade fails",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, nil, suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
expPass: false,
},
}
for _, tc := range cases {
tc := tc
clientA, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, ibctesting.Tendermint)
tc.setup()
_, err := client.HandleMsgUpgradeClient(
suite.chainA.GetContext(), suite.chainA.App.IBCKeeper.ClientKeeper, msg,
)
if tc.expPass {
suite.Require().NoError(err, "upgrade handler failed on valid case: %s", tc.name)
newClient, ok := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(ok)
suite.Require().Equal(upgradedClient, newClient)
} else {
suite.Require().Error(err, "upgrade handler passed on invalid case: %s", tc.name)
}
}
}

View File

@ -65,7 +65,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H
consensusHeight = types.GetSelfHeight(ctx)
}
k.Logger(ctx).Info(fmt.Sprintf("client %s updated height %d", clientID, consensusHeight))
k.Logger(ctx).Info("client state updated", "client-id", clientID, "height", consensusHeight)
// emitting events in the keeper emits for both begin block and handler client updates
ctx.EventManager().EmitEvent(
@ -80,6 +80,41 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H
return nil
}
// UpgradeClient upgrades the client to a new client state if this new client was committed to
// by the old client at the specified upgrade height
func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient exported.ClientState, proofUpgrade []byte) error {
clientState, found := k.GetClientState(ctx, clientID)
if !found {
return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID)
}
// prevent upgrade if current client is frozen
if clientState.IsFrozen() {
return sdkerrors.Wrapf(types.ErrClientFrozen, "cannot update client with ID %s", clientID)
}
err := clientState.VerifyUpgrade(ctx, k.cdc, k.ClientStore(ctx, clientID), upgradedClient, proofUpgrade)
if err != nil {
return sdkerrors.Wrapf(err, "cannot upgrade client with ID: %s", clientID)
}
k.SetClientState(ctx, clientID, upgradedClient)
k.Logger(ctx).Info("client state upgraded", "client-id", clientID, "height", upgradedClient.GetLatestHeight())
// emitting events in the keeper emits for client upgrades
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeUpgradeClient,
sdk.NewAttribute(types.AttributeKeyClientID, clientID),
sdk.NewAttribute(types.AttributeKeyClientType, clientState.ClientType()),
sdk.NewAttribute(types.AttributeKeyConsensusHeight, upgradedClient.GetLatestHeight().String()),
),
)
return nil
}
// CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the
// client if so.
func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour exported.Misbehaviour) error {

View File

@ -13,7 +13,11 @@ import (
localhosttypes "github.com/cosmos/cosmos-sdk/x/ibc/09-localhost/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/ibc/exported"
solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/solomachine/types"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
ibctestingmock "github.com/cosmos/cosmos-sdk/x/ibc/testing/mock"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
func (suite *KeeperTestSuite) TestCreateClient() {
@ -32,11 +36,11 @@ func (suite *KeeperTestSuite) TestCreateClient() {
i := i
if tc.expPanic {
suite.Require().Panics(func() {
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
suite.keeper.CreateClient(suite.ctx, tc.clientID, clientState, suite.consensusState)
}, "Msg %d didn't panic: %s", i, tc.msg)
} else {
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
if tc.expPass {
suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg)
}
@ -79,7 +83,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
expPass bool
}{
{"valid update", func() error {
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
// store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height
@ -97,7 +101,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
return err
}, true},
{"valid past update", func() error {
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
suite.Require().NoError(err)
@ -130,7 +134,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
return nil
}, false},
{"consensus state not found", func() error {
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
updateHeader = createFutureUpdateFn(suite)
@ -144,7 +148,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
return nil
}, false},
{"valid past update before client was frozen", func() error {
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
clientState.FrozenHeight = types.NewHeight(0, testClientHeight.EpochHeight-1)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
suite.Require().NoError(err)
@ -164,7 +168,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
return nil
}, true},
{"invalid header", func() error {
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
suite.Require().NoError(err)
updateHeader = createPastUpdateFn(suite)
@ -232,6 +236,156 @@ func (suite *KeeperTestSuite) TestUpdateClientLocalhost() {
suite.Require().Equal(localhostClient.GetLatestHeight().(types.Height).Increment(), clientState.GetLatestHeight())
}
func (suite *KeeperTestSuite) TestUpgradeClient() {
var (
upgradedClient exported.ClientState
clientA string
proofUpgrade []byte
)
testCases := []struct {
name string
setup func()
expPass bool
}{
{
name: "successful upgrade to a new tendermint client",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: true,
},
{
name: "successful upgrade to a solomachine client",
setup: func() {
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
// demonstrate that VerifyUpgrade allows for arbitrary changes to clienstate structure so long as
// previous chain committed to the change
upgradedClient = ibctesting.NewSolomachine(suite.T(), suite.cdc, clientA, "diversifier", 1).ClientState()
soloClient, _ := upgradedClient.(*solomachinetypes.ClientState)
// change sequence to be higher height than latest current client height
soloClient.Sequence = cs.GetLatestHeight().GetEpochHeight() + 100
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found = suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: true,
},
{
name: "client state not found",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
clientA = "wrongclientid"
},
expPass: false,
},
{
name: "client state frozen",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
// set frozen client in store
tmClient, ok := cs.(*ibctmtypes.ClientState)
suite.Require().True(ok)
tmClient.FrozenHeight = types.NewHeight(0, 1)
suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, tmClient)
},
expPass: false,
},
{
name: "tendermint client VerifyUpgrade fails",
setup: func() {
upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// change upgradedClient client-specified parameters
upgradedClient = ibctmtypes.NewClientState("wrongchainID", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, true, true)
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: false,
},
}
for _, tc := range testCases {
tc := tc
clientA, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, ibctesting.Tendermint)
tc.setup()
err := suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, proofUpgrade)
if tc.expPass {
suite.Require().NoError(err, "verify upgrade failed on valid case: %s", tc.name)
} else {
suite.Require().Error(err, "verify upgrade passed on invalid case: %s", tc.name)
}
}
}
func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
altPrivVal := ibctestingmock.NewPV()
altPubKey, err := altPrivVal.GetPubKey()
@ -276,7 +430,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
suite.consensusState.NextValidatorsHash = bothValsHash
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
return err
@ -293,7 +447,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
suite.consensusState.NextValidatorsHash = valsHash
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
// store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height
@ -320,7 +474,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
suite.consensusState.NextValidatorsHash = valsHash
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
// store trusted consensus state for Header2
@ -347,7 +501,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
suite.consensusState.NextValidatorsHash = valsHash
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
// intermediate consensus state at height + 3 is not created
return err
@ -364,7 +518,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
suite.consensusState.NextValidatorsHash = valsHash
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
// intermediate consensus state at height + 3 is not created
return err
@ -387,7 +541,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
func() error {
suite.consensusState.NextValidatorsHash = bothValsHash
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
clientState.FrozenHeight = types.NewHeight(0, 1)
@ -406,7 +560,7 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
ClientId: testClientID,
},
func() error {
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
if err != nil {
return err
}

View File

@ -43,7 +43,7 @@ func (suite *KeeperTestSuite) TestQueryClientState() {
{
"success",
func() {
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
var err error
@ -209,7 +209,7 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() {
{
"success latest height",
func() {
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
cs := ibctmtypes.NewConsensusState(
suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), nil,
)

View File

@ -17,6 +17,7 @@ import (
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
"github.com/cosmos/cosmos-sdk/x/ibc/exported"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
// Keeper represents a type that grants read and write permissions to any client
@ -249,6 +250,15 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS
return sdkerrors.Wrapf(types.ErrInvalidClient, "unbonding period must be greater than trusting period. unbonding period (%d) < trusting period (%d)",
tmClient.UnbondingPeriod, tmClient.TrustingPeriod)
}
if tmClient.UpgradePath != nil {
// For now, SDK IBC implementation assumes that upgrade path (if defined) is defined by SDK upgrade module
expectedUpgradePath := fmt.Sprintf("/%s/%s", upgradetypes.StoreKey, upgradetypes.KeyUpgradedClient)
if tmClient.UpgradePath.String() != expectedUpgradePath {
return sdkerrors.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %s, got %s",
expectedUpgradePath, tmClient.UpgradePath)
}
}
return nil
}

View File

@ -41,8 +41,11 @@ const (
maxClockDrift time.Duration = time.Second * 10
)
var testClientHeight = types.NewHeight(0, 5)
var testClientHeightEpoch1 = types.NewHeight(1, 5)
var (
testClientHeight = types.NewHeight(0, 5)
testClientHeightEpoch1 = types.NewHeight(1, 5)
upgradeHeight = types.NewHeight(1, 1)
)
type KeeperTestSuite struct {
suite.Suite
@ -117,7 +120,7 @@ func TestKeeperTestSuite(t *testing.T) {
}
func (suite *KeeperTestSuite) TestSetClientState() {
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
@ -137,6 +140,7 @@ func (suite *KeeperTestSuite) TestSetClientConsensusState() {
}
func (suite *KeeperTestSuite) TestValidateSelfClient() {
badUpgradePath := commitmenttypes.NewMerklePath([]string{"bad", "upgrade", "path"})
testCases := []struct {
name string
clientState exported.ClientState
@ -144,7 +148,12 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() {
}{
{
"success",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
true,
},
{
"success with nil UpgradePath",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), nil, false, false),
true,
},
{
@ -154,42 +163,47 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() {
},
{
"frozen client",
&ibctmtypes.ClientState{testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false},
&ibctmtypes.ClientState{testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false},
false,
},
{
"incorrect chainID",
ibctmtypes.NewClientState("gaiatestnet", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState("gaiatestnet", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid client height",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, testClientHeight.EpochHeight+10), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, testClientHeight.EpochHeight+10), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid client epoch",
ibctmtypes.NewClientState(testChainIDEpoch1, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightEpoch1, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainIDEpoch1, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightEpoch1, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid proof specs",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, nil, false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, nil, &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid trust level",
ibctmtypes.NewClientState(testChainID, ibctmtypes.Fraction{0, 1}, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.Fraction{0, 1}, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid unbonding period",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+10, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+10, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid trusting period",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, ubdPeriod+10, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, ubdPeriod+10, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
false,
},
{
"invalid upgrade path",
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &badUpgradePath, false, false),
false,
},
}
@ -212,9 +226,9 @@ func (suite KeeperTestSuite) TestGetAllClients() {
testClientID2, testClientID3, testClientID,
}
expClients := []exported.ClientState{
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
}
for i := range expClients {
@ -236,9 +250,9 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() {
testClientID2, testClientID3, testClientID,
}
expClients := []exported.ClientState{
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
}
expGenClients := make([]types.IdentifiedClientState, len(expClients))
@ -286,7 +300,7 @@ func (suite KeeperTestSuite) TestGetConsensusState() {
func (suite KeeperTestSuite) TestConsensusStateHelpers() {
// initial setup
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), false, false)
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState)

View File

@ -34,12 +34,7 @@ func NewIdentifiedClientState(clientID string, clientState exported.ClientState)
// UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces
func (ics IdentifiedClientState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
var clientState exported.ClientState
err := unpacker.UnpackAny(ics.ClientState, &clientState)
if err != nil {
return err
}
return nil
return unpacker.UnpackAny(ics.ClientState, new(exported.ClientState))
}
// NewConsensusStateWithHeight creates a new ConsensusStateWithHeight instance
@ -62,10 +57,5 @@ func NewConsensusStateWithHeight(height Height, consensusState exported.Consensu
// UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces
func (cswh ConsensusStateWithHeight) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
var consensusState exported.ConsensusState
err := unpacker.UnpackAny(cswh.ConsensusState, &consensusState)
if err != nil {
return err
}
return nil
return unpacker.UnpackAny(cswh.ConsensusState, new(exported.ConsensusState))
}

View File

@ -328,6 +328,79 @@ func (m *MsgUpdateClient) XXX_DiscardUnknown() {
var xxx_messageInfo_MsgUpdateClient proto.InternalMessageInfo
// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state
type MsgUpgradeClient struct {
// client unique identifier
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"`
// upgraded client state
ClientState *types.Any `protobuf:"bytes,2,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"`
// proof that old chain committed to new client
ProofUpgrade []byte `protobuf:"bytes,3,opt,name=proof_upgrade,json=proofUpgrade,proto3" json:"proof_upgrade,omitempty" yaml:"proof_upgrade"`
// signer address
Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"`
}
func (m *MsgUpgradeClient) Reset() { *m = MsgUpgradeClient{} }
func (m *MsgUpgradeClient) String() string { return proto.CompactTextString(m) }
func (*MsgUpgradeClient) ProtoMessage() {}
func (*MsgUpgradeClient) Descriptor() ([]byte, []int) {
return fileDescriptor_226f80e576f20abd, []int{6}
}
func (m *MsgUpgradeClient) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *MsgUpgradeClient) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_MsgUpgradeClient.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 *MsgUpgradeClient) XXX_Merge(src proto.Message) {
xxx_messageInfo_MsgUpgradeClient.Merge(m, src)
}
func (m *MsgUpgradeClient) XXX_Size() int {
return m.Size()
}
func (m *MsgUpgradeClient) XXX_DiscardUnknown() {
xxx_messageInfo_MsgUpgradeClient.DiscardUnknown(m)
}
var xxx_messageInfo_MsgUpgradeClient proto.InternalMessageInfo
func (m *MsgUpgradeClient) GetClientId() string {
if m != nil {
return m.ClientId
}
return ""
}
func (m *MsgUpgradeClient) GetClientState() *types.Any {
if m != nil {
return m.ClientState
}
return nil
}
func (m *MsgUpgradeClient) GetProofUpgrade() []byte {
if m != nil {
return m.ProofUpgrade
}
return nil
}
func (m *MsgUpgradeClient) GetSigner() string {
if m != nil {
return m.Signer
}
return ""
}
// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for
// light client misbehaviour.
type MsgSubmitMisbehaviour struct {
@ -343,7 +416,7 @@ func (m *MsgSubmitMisbehaviour) Reset() { *m = MsgSubmitMisbehaviour{} }
func (m *MsgSubmitMisbehaviour) String() string { return proto.CompactTextString(m) }
func (*MsgSubmitMisbehaviour) ProtoMessage() {}
func (*MsgSubmitMisbehaviour) Descriptor() ([]byte, []int) {
return fileDescriptor_226f80e576f20abd, []int{6}
return fileDescriptor_226f80e576f20abd, []int{7}
}
func (m *MsgSubmitMisbehaviour) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -391,7 +464,7 @@ type Height struct {
func (m *Height) Reset() { *m = Height{} }
func (*Height) ProtoMessage() {}
func (*Height) Descriptor() ([]byte, []int) {
return fileDescriptor_226f80e576f20abd, []int{7}
return fileDescriptor_226f80e576f20abd, []int{8}
}
func (m *Height) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -427,6 +500,7 @@ func init() {
proto.RegisterType((*ClientUpdateProposal)(nil), "ibc.client.ClientUpdateProposal")
proto.RegisterType((*MsgCreateClient)(nil), "ibc.client.MsgCreateClient")
proto.RegisterType((*MsgUpdateClient)(nil), "ibc.client.MsgUpdateClient")
proto.RegisterType((*MsgUpgradeClient)(nil), "ibc.client.MsgUpgradeClient")
proto.RegisterType((*MsgSubmitMisbehaviour)(nil), "ibc.client.MsgSubmitMisbehaviour")
proto.RegisterType((*Height)(nil), "ibc.client.Height")
}
@ -434,47 +508,50 @@ func init() {
func init() { proto.RegisterFile("ibc/client/client.proto", fileDescriptor_226f80e576f20abd) }
var fileDescriptor_226f80e576f20abd = []byte{
// 632 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xbd, 0x6e, 0xd4, 0x40,
0x10, 0xbe, 0xbd, 0x3b, 0x4e, 0xb9, 0x75, 0x44, 0x22, 0x73, 0x97, 0x5c, 0x52, 0xd8, 0xa7, 0x15,
0x45, 0x0a, 0x62, 0x87, 0xa3, 0x41, 0xd7, 0x71, 0x69, 0x88, 0x44, 0x50, 0xe4, 0x08, 0xf1, 0xd3,
0x44, 0xfe, 0xd9, 0xd8, 0x2b, 0xce, 0x5e, 0xcb, 0xbb, 0x46, 0xdc, 0x1b, 0x20, 0x2a, 0x24, 0x28,
0x28, 0x28, 0x52, 0xe5, 0x0d, 0xe8, 0x78, 0x80, 0x94, 0x29, 0xa9, 0x2c, 0x94, 0x34, 0xd4, 0xf7,
0x04, 0xc8, 0xbb, 0x0e, 0x67, 0xe7, 0x8f, 0x28, 0x15, 0x95, 0x77, 0x66, 0x67, 0xbe, 0xf9, 0xe6,
0x9b, 0x91, 0x17, 0x2e, 0x13, 0xc7, 0x35, 0xdd, 0x31, 0xc1, 0x11, 0x2f, 0x3e, 0x46, 0x9c, 0x50,
0x4e, 0x55, 0x48, 0x1c, 0xd7, 0x90, 0x9e, 0xd5, 0x8e, 0x4f, 0x7d, 0x2a, 0xdc, 0x66, 0x7e, 0x92,
0x11, 0xab, 0x2b, 0x3e, 0xa5, 0xfe, 0x18, 0x9b, 0xc2, 0x72, 0xd2, 0x7d, 0xd3, 0x8e, 0x26, 0xf2,
0x0a, 0x7d, 0x03, 0xb0, 0xbb, 0xe5, 0xe1, 0x88, 0x93, 0x7d, 0x82, 0xbd, 0x4d, 0x81, 0xb2, 0xcb,
0x6d, 0x8e, 0xd5, 0x87, 0xb0, 0x2d, 0x41, 0xf7, 0x88, 0xd7, 0x03, 0x7d, 0xb0, 0xd6, 0x1e, 0x75,
0xa6, 0x99, 0xbe, 0x38, 0xb1, 0xc3, 0xf1, 0x10, 0xfd, 0xbd, 0x42, 0xd6, 0x9c, 0x3c, 0x6f, 0x79,
0xea, 0x0e, 0x9c, 0x2f, 0xfc, 0x2c, 0x87, 0xe8, 0xd5, 0xfb, 0x60, 0x4d, 0x19, 0x74, 0x0c, 0x59,
0xde, 0x38, 0x2b, 0x6f, 0x3c, 0x89, 0x26, 0xa3, 0xe5, 0x69, 0xa6, 0xdf, 0xab, 0x60, 0x89, 0x1c,
0x64, 0x29, 0xee, 0x8c, 0x04, 0x3a, 0x04, 0xb0, 0xb7, 0x49, 0x23, 0x86, 0x23, 0x96, 0x32, 0xe1,
0x7a, 0x49, 0x78, 0xf0, 0x14, 0x13, 0x3f, 0xe0, 0xea, 0x06, 0x6c, 0x05, 0xe2, 0x24, 0xe8, 0x29,
0x03, 0xd5, 0x98, 0x29, 0x61, 0xc8, 0x98, 0x51, 0xf3, 0x28, 0xd3, 0x6b, 0x56, 0x11, 0xa7, 0xbe,
0x82, 0x0b, 0xee, 0x19, 0xda, 0x0d, 0x38, 0xae, 0x4c, 0x33, 0xbd, 0x9b, 0x73, 0x44, 0xe7, 0xb2,
0x90, 0x75, 0xd7, 0xad, 0xb0, 0x42, 0x3f, 0x00, 0xec, 0x4a, 0xf5, 0xaa, 0x74, 0xd9, 0x6d, 0x74,
0x8c, 0xe1, 0xe2, 0xb9, 0x82, 0xac, 0x57, 0xef, 0x37, 0xd6, 0x94, 0xc1, 0xfd, 0x72, 0x8b, 0x57,
0x09, 0x33, 0xd2, 0xf3, 0xa6, 0xa7, 0x99, 0xbe, 0x5c, 0xd4, 0x38, 0x87, 0x85, 0xac, 0x85, 0x2a,
0x7b, 0x86, 0xbe, 0x03, 0xd8, 0x91, 0xf4, 0x5f, 0xc4, 0x9e, 0xcd, 0xf1, 0x4e, 0x42, 0x63, 0xca,
0xec, 0xb1, 0xda, 0x81, 0x77, 0x38, 0xe1, 0x63, 0x2c, 0x99, 0x5b, 0xd2, 0x50, 0xfb, 0x50, 0xf1,
0x30, 0x73, 0x13, 0x12, 0x73, 0x42, 0x23, 0xa1, 0x61, 0xdb, 0x2a, 0xbb, 0xaa, 0x5d, 0x37, 0x6e,
0xd4, 0xf5, 0x83, 0x7c, 0x9c, 0xb6, 0x87, 0x93, 0x5e, 0xf3, 0xea, 0x99, 0x58, 0x45, 0xcc, 0xb0,
0xf9, 0xe1, 0x40, 0xaf, 0xa1, 0xcf, 0x75, 0xb8, 0xb0, 0xcd, 0xfc, 0xcd, 0x04, 0xdb, 0x1c, 0xcb,
0x06, 0xfe, 0x8b, 0xc5, 0x55, 0x5f, 0x5f, 0xdc, 0xb4, 0xc6, 0x35, 0xa0, 0xab, 0xd3, 0x4c, 0x5f,
0xba, 0x74, 0x5a, 0x17, 0x56, 0x4d, 0x5d, 0x82, 0x2d, 0x46, 0xfc, 0xa8, 0xd0, 0xa9, 0x6d, 0x15,
0xd6, 0x70, 0x2e, 0x57, 0xe4, 0x77, 0xae, 0xca, 0x17, 0x20, 0x54, 0x91, 0xa3, 0xbc, 0xbd, 0x2a,
0xb3, 0x81, 0xd4, 0xff, 0x3d, 0x90, 0x12, 0xad, 0xc6, 0x15, 0xb4, 0x0e, 0x01, 0xec, 0x6e, 0x33,
0x7f, 0x37, 0x75, 0x42, 0xc2, 0xb7, 0x09, 0x73, 0x70, 0x60, 0xbf, 0x23, 0x34, 0x4d, 0x6e, 0x43,
0xee, 0x31, 0x9c, 0x0f, 0x4b, 0x10, 0xd7, 0x52, 0xac, 0x44, 0xde, 0x80, 0xe8, 0x47, 0x00, 0x5b,
0xc5, 0x3f, 0x66, 0x08, 0xe7, 0x71, 0x4c, 0xdd, 0x60, 0x2f, 0x4a, 0x43, 0x07, 0x27, 0x82, 0x5c,
0xb3, 0xbc, 0x03, 0xe5, 0x5b, 0x64, 0x29, 0xc2, 0x7c, 0x2e, 0xac, 0x59, 0x6e, 0xf1, 0x97, 0xaa,
0x5f, 0x9e, 0x2b, 0x6f, 0xcf, 0x72, 0x65, 0x5d, 0x49, 0xe6, 0xeb, 0x81, 0x5e, 0x1b, 0x3d, 0x3b,
0x3a, 0xd1, 0xc0, 0xf1, 0x89, 0x06, 0x7e, 0x9d, 0x68, 0xe0, 0xd3, 0xa9, 0x56, 0x3b, 0x3e, 0xd5,
0x6a, 0x3f, 0x4f, 0xb5, 0xda, 0x9b, 0x81, 0x4f, 0x78, 0x90, 0x3a, 0x86, 0x4b, 0x43, 0xd3, 0xa5,
0x2c, 0xa4, 0xac, 0xf8, 0xac, 0x33, 0xef, 0xad, 0xf9, 0xde, 0xcc, 0x1f, 0x8c, 0x8d, 0xc1, 0x7a,
0xf1, 0x66, 0xf0, 0x49, 0x8c, 0x99, 0xd3, 0x12, 0xc2, 0x3c, 0xfa, 0x13, 0x00, 0x00, 0xff, 0xff,
0xe9, 0x68, 0x4f, 0xc2, 0x4e, 0x06, 0x00, 0x00,
// 675 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0x3d, 0x6f, 0xd3, 0x4e,
0x1c, 0xce, 0x25, 0xf9, 0x47, 0xcd, 0x25, 0x7f, 0x5a, 0x99, 0xa4, 0x4d, 0x3b, 0xc4, 0xd1, 0x89,
0xa1, 0x03, 0xb5, 0x4b, 0x58, 0x50, 0x24, 0x06, 0xd2, 0x85, 0x4a, 0x14, 0x55, 0xae, 0x10, 0x2f,
0x4b, 0xe5, 0x97, 0xab, 0x73, 0x22, 0xf1, 0x59, 0xbe, 0x33, 0x22, 0xdf, 0x00, 0x31, 0x21, 0xc1,
0xc0, 0xc0, 0xd0, 0x89, 0x6f, 0xc0, 0xc6, 0x07, 0xe8, 0xd8, 0x91, 0xc9, 0x42, 0xed, 0xc2, 0xc4,
0x90, 0x4f, 0x80, 0x7c, 0x77, 0x25, 0x76, 0xdb, 0x94, 0x2a, 0x53, 0x27, 0xdf, 0xef, 0xfd, 0xf9,
0x3d, 0xcf, 0xe9, 0x0c, 0x57, 0x88, 0xe3, 0x9a, 0xee, 0x90, 0xe0, 0x80, 0xab, 0x8f, 0x11, 0x46,
0x94, 0x53, 0x0d, 0x12, 0xc7, 0x35, 0xa4, 0x67, 0xad, 0xe1, 0x53, 0x9f, 0x0a, 0xb7, 0x99, 0x9e,
0x64, 0xc6, 0xda, 0xaa, 0x4f, 0xa9, 0x3f, 0xc4, 0xa6, 0xb0, 0x9c, 0xf8, 0xc0, 0xb4, 0x83, 0xb1,
0x0c, 0xa1, 0x2f, 0x00, 0x36, 0xb7, 0x3d, 0x1c, 0x70, 0x72, 0x40, 0xb0, 0xb7, 0x25, 0xba, 0xec,
0x71, 0x9b, 0x63, 0xed, 0x1e, 0xac, 0xca, 0xa6, 0xfb, 0xc4, 0x6b, 0x81, 0x0e, 0x58, 0xaf, 0xf6,
0x1b, 0x93, 0x44, 0x5f, 0x1a, 0xdb, 0xa3, 0x61, 0x0f, 0xfd, 0x0d, 0x21, 0x6b, 0x41, 0x9e, 0xb7,
0x3d, 0x6d, 0x17, 0xd6, 0x95, 0x9f, 0xa5, 0x2d, 0x5a, 0xc5, 0x0e, 0x58, 0xaf, 0x75, 0x1b, 0x86,
0x1c, 0x6f, 0x9c, 0x8d, 0x37, 0x1e, 0x05, 0xe3, 0xfe, 0xca, 0x24, 0xd1, 0x6f, 0xe7, 0x7a, 0x89,
0x1a, 0x64, 0xd5, 0xdc, 0x29, 0x08, 0xf4, 0x15, 0xc0, 0xd6, 0x16, 0x0d, 0x18, 0x0e, 0x58, 0xcc,
0x84, 0xeb, 0x39, 0xe1, 0x83, 0xc7, 0x98, 0xf8, 0x03, 0xae, 0x6d, 0xc2, 0xca, 0x40, 0x9c, 0x04,
0xbc, 0x5a, 0x57, 0x33, 0xa6, 0x4c, 0x18, 0x32, 0xa7, 0x5f, 0x3e, 0x4a, 0xf4, 0x82, 0xa5, 0xf2,
0xb4, 0x17, 0x70, 0xd1, 0x3d, 0xeb, 0x76, 0x0d, 0x8c, 0xab, 0x93, 0x44, 0x6f, 0xa6, 0x18, 0xd1,
0xb9, 0x2a, 0x64, 0xdd, 0x72, 0x73, 0xa8, 0xd0, 0x77, 0x00, 0x9b, 0x92, 0xbd, 0x3c, 0x5c, 0x36,
0x0f, 0x8f, 0x21, 0x5c, 0x3a, 0x37, 0x90, 0xb5, 0x8a, 0x9d, 0xd2, 0x7a, 0xad, 0x7b, 0x27, 0xbb,
0xe2, 0x2c, 0x62, 0xfa, 0x7a, 0xba, 0xf4, 0x24, 0xd1, 0x57, 0xd4, 0x8c, 0x73, 0xbd, 0x90, 0xb5,
0x98, 0x47, 0xcf, 0xd0, 0x37, 0x00, 0x1b, 0x12, 0xfe, 0xb3, 0xd0, 0xb3, 0x39, 0xde, 0x8d, 0x68,
0x48, 0x99, 0x3d, 0xd4, 0x1a, 0xf0, 0x3f, 0x4e, 0xf8, 0x10, 0x4b, 0xe4, 0x96, 0x34, 0xb4, 0x0e,
0xac, 0x79, 0x98, 0xb9, 0x11, 0x09, 0x39, 0xa1, 0x81, 0xe0, 0xb0, 0x6a, 0x65, 0x5d, 0xf9, 0xad,
0x4b, 0xd7, 0xda, 0xfa, 0x6e, 0x2a, 0xa7, 0xed, 0xe1, 0xa8, 0x55, 0x9e, 0xad, 0x89, 0xa5, 0x72,
0x7a, 0xe5, 0x77, 0x87, 0x7a, 0x01, 0x7d, 0x2c, 0xc2, 0xc5, 0x1d, 0xe6, 0x6f, 0x45, 0xd8, 0xe6,
0x58, 0x2e, 0x70, 0x23, 0x2e, 0xae, 0xf6, 0xf2, 0xe2, 0x4d, 0x2b, 0x5d, 0xd1, 0x74, 0x6d, 0x92,
0xe8, 0xcb, 0x97, 0xaa, 0x75, 0xe1, 0xaa, 0x69, 0xcb, 0xb0, 0xc2, 0x88, 0x1f, 0x28, 0x9e, 0xaa,
0x96, 0xb2, 0x7a, 0x0b, 0x29, 0x23, 0xbf, 0x52, 0x56, 0x3e, 0x01, 0xc1, 0x8a, 0x94, 0x72, 0x7e,
0x56, 0xa6, 0x82, 0x14, 0xff, 0x2d, 0x48, 0x06, 0x56, 0x69, 0x06, 0xac, 0xdf, 0x00, 0x2e, 0x09,
0x58, 0x7e, 0x64, 0x7b, 0x37, 0x4a, 0xad, 0x87, 0xf0, 0xff, 0x30, 0xa2, 0xf4, 0x60, 0x3f, 0x96,
0xd8, 0xc4, 0x0a, 0xf5, 0x7e, 0x6b, 0x92, 0xe8, 0x0d, 0x59, 0x9c, 0x0b, 0x23, 0xab, 0x2e, 0x6c,
0xb5, 0xc9, 0x2c, 0x45, 0xd2, 0xd7, 0xab, 0xb9, 0xc3, 0xfc, 0xbd, 0xd8, 0x19, 0x11, 0xbe, 0x43,
0x98, 0x83, 0x07, 0xf6, 0x1b, 0x42, 0xe3, 0x68, 0x9e, 0xad, 0x1f, 0xc0, 0xfa, 0x28, 0xd3, 0xe2,
0x4a, 0x4d, 0x72, 0x99, 0xd7, 0x50, 0xe6, 0x3d, 0x80, 0x15, 0xf5, 0xa8, 0xf6, 0x60, 0x1d, 0x87,
0xd4, 0x1d, 0xec, 0x07, 0xf1, 0xc8, 0xc1, 0x91, 0x00, 0x57, 0xce, 0xd2, 0x98, 0x8d, 0x22, 0xab,
0x26, 0xcc, 0xa7, 0xc2, 0x9a, 0xd6, 0xaa, 0x67, 0xb9, 0x78, 0x79, 0xad, 0x8c, 0x9e, 0xd5, 0xca,
0xb9, 0x12, 0xcc, 0xe7, 0x43, 0xbd, 0xd0, 0x7f, 0x72, 0x74, 0xd2, 0x06, 0xc7, 0x27, 0x6d, 0xf0,
0xf3, 0xa4, 0x0d, 0x3e, 0x9c, 0xb6, 0x0b, 0xc7, 0xa7, 0xed, 0xc2, 0x8f, 0xd3, 0x76, 0xe1, 0x55,
0xd7, 0x27, 0x7c, 0x10, 0x3b, 0x86, 0x4b, 0x47, 0xa6, 0x4b, 0xd9, 0x88, 0x32, 0xf5, 0xd9, 0x60,
0xde, 0x6b, 0xf3, 0xad, 0x99, 0xfe, 0x21, 0x37, 0xbb, 0x1b, 0xea, 0x27, 0xc9, 0xc7, 0x21, 0x66,
0x4e, 0x45, 0x10, 0x73, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xba, 0xc4, 0xe6, 0x7d, 0x3f,
0x07, 0x00, 0x00,
}
func (m *IdentifiedClientState) Marshal() (dAtA []byte, err error) {
@ -774,6 +851,62 @@ func (m *MsgUpdateClient) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *MsgUpgradeClient) 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 *MsgUpgradeClient) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *MsgUpgradeClient) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Signer) > 0 {
i -= len(m.Signer)
copy(dAtA[i:], m.Signer)
i = encodeVarintClient(dAtA, i, uint64(len(m.Signer)))
i--
dAtA[i] = 0x22
}
if len(m.ProofUpgrade) > 0 {
i -= len(m.ProofUpgrade)
copy(dAtA[i:], m.ProofUpgrade)
i = encodeVarintClient(dAtA, i, uint64(len(m.ProofUpgrade)))
i--
dAtA[i] = 0x1a
}
if m.ClientState != nil {
{
size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintClient(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.ClientId) > 0 {
i -= len(m.ClientId)
copy(dAtA[i:], m.ClientId)
i = encodeVarintClient(dAtA, i, uint64(len(m.ClientId)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *MsgSubmitMisbehaviour) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -989,6 +1122,31 @@ func (m *MsgUpdateClient) Size() (n int) {
return n
}
func (m *MsgUpgradeClient) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.ClientId)
if l > 0 {
n += 1 + l + sovClient(uint64(l))
}
if m.ClientState != nil {
l = m.ClientState.Size()
n += 1 + l + sovClient(uint64(l))
}
l = len(m.ProofUpgrade)
if l > 0 {
n += 1 + l + sovClient(uint64(l))
}
l = len(m.Signer)
if l > 0 {
n += 1 + l + sovClient(uint64(l))
}
return n
}
func (m *MsgSubmitMisbehaviour) Size() (n int) {
if m == nil {
return 0
@ -1920,6 +2078,193 @@ func (m *MsgUpdateClient) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *MsgUpgradeClient) 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: MsgUpgradeClient: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MsgUpgradeClient: 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 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.ClientId = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClientState", 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.ClientState == nil {
m.ClientState = &types.Any{}
}
if err := m.ClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgrade", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowClient
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthClient
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthClient
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ProofUpgrade = append(m.ProofUpgrade[:0], dAtA[iNdEx:postIndex]...)
if m.ProofUpgrade == nil {
m.ProofUpgrade = []byte{}
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipClient(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthClient
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthClient
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *MsgSubmitMisbehaviour) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@ -30,7 +30,7 @@ func (suite *TypesTestSuite) TestPackClientState() {
},
{
"tendermint client",
ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
true,
},
{

View File

@ -28,4 +28,5 @@ var (
ErrSelfConsensusStateNotFound = sdkerrors.Register(SubModuleName, 21, "self consensus state not found")
ErrUpdateClientFailed = sdkerrors.Register(SubModuleName, 22, "unable to update light client")
ErrInvalidUpdateClientProposal = sdkerrors.Register(SubModuleName, 23, "invalid update client proposal")
ErrInvalidUpgradeClient = sdkerrors.Register(SubModuleName, 24, "invalid client upgrade")
)

View File

@ -17,6 +17,7 @@ const (
var (
EventTypeCreateClient = "create_client"
EventTypeUpdateClient = "update_client"
EventTypeUpgradeClient = "upgrade_client"
EventTypeSubmitMisbehaviour = "client_misbehaviour"
EventTypeUpdateClientProposal = "update_client_proposal"

View File

@ -72,7 +72,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
types.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight),
@ -100,7 +100,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
"/~@$*", ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
"/~@$*", ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
types.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight),
@ -128,7 +128,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
types.NewIdentifiedClientState(exported.Localhost, localhosttypes.NewClientState("chaindID", types.ZeroHeight())),
},
@ -142,7 +142,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
types.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight),
@ -170,7 +170,7 @@ func TestValidateGenesis(t *testing.T) {
genState: types.NewGenesisState(
[]types.IdentifiedClientState{
types.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
types.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight),

View File

@ -12,6 +12,7 @@ import (
const (
TypeMsgCreateClient string = "create_client"
TypeMsgUpdateClient string = "update_client"
TypeMsgUpgradeClient string = "upgrade_client"
TypeMsgSubmitMisbehaviour string = "submit_misbehaviour"
)
@ -19,10 +20,12 @@ var (
_ sdk.Msg = &MsgCreateClient{}
_ sdk.Msg = &MsgUpdateClient{}
_ sdk.Msg = &MsgSubmitMisbehaviour{}
_ sdk.Msg = &MsgUpgradeClient{}
_ codectypes.UnpackInterfacesMessage = MsgCreateClient{}
_ codectypes.UnpackInterfacesMessage = MsgUpdateClient{}
_ codectypes.UnpackInterfacesMessage = MsgSubmitMisbehaviour{}
_ codectypes.UnpackInterfacesMessage = MsgUpgradeClient{}
)
// NewMsgCreateClient creates a new MsgCreateClient instance
@ -107,12 +110,7 @@ func (msg MsgCreateClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) err
}
var consensusState exported.ConsensusState
err = unpacker.UnpackAny(msg.ConsensusState, &consensusState)
if err != nil {
return err
}
return nil
return unpacker.UnpackAny(msg.ConsensusState, &consensusState)
}
// NewMsgUpdateClient creates a new MsgUpdateClient instance
@ -175,12 +173,72 @@ func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress {
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg MsgUpdateClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
var header exported.Header
err := unpacker.UnpackAny(msg.Header, &header)
return unpacker.UnpackAny(msg.Header, &header)
}
// NewMsgUpgradeClient creates a new MsgUpgradeClient instance
// nolint: interfacer
func NewMsgUpgradeClient(clientID string, clientState exported.ClientState, proofUpgrade []byte, signer sdk.AccAddress) (*MsgUpgradeClient, error) {
anyClient, err := PackClientState(clientState)
if err != nil {
return nil, err
}
return &MsgUpgradeClient{
ClientId: clientID,
ClientState: anyClient,
ProofUpgrade: proofUpgrade,
Signer: signer.String(),
}, nil
}
// Route implements sdk.Msg
func (msg MsgUpgradeClient) Route() string {
return host.RouterKey
}
// Type implements sdk.Msg
func (msg MsgUpgradeClient) Type() string {
return TypeMsgUpgradeClient
}
// ValidateBasic implements sdk.Msg
func (msg MsgUpgradeClient) ValidateBasic() error {
clientState, err := UnpackClientState(msg.ClientState)
if err != nil {
return err
}
if err := clientState.Validate(); err != nil {
return err
}
if len(msg.ProofUpgrade) == 0 {
return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade cannot be empty")
}
_, err = sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err)
}
return host.ClientIdentifierValidator(msg.ClientId)
}
return nil
// GetSignBytes implements sdk.Msg
func (msg MsgUpgradeClient) GetSignBytes() []byte {
return sdk.MustSortJSON(SubModuleCdc.MustMarshalJSON(&msg))
}
// GetSigners implements sdk.Msg
func (msg MsgUpgradeClient) GetSigners() []sdk.AccAddress {
accAddr, err := sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
panic(err)
}
return []sdk.AccAddress{accAddr}
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg MsgUpgradeClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
var clientState exported.ClientState
return unpacker.UnpackAny(msg.ClientState, &clientState)
}
// NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance.
@ -247,10 +305,5 @@ func (msg MsgSubmitMisbehaviour) GetSigners() []sdk.AccAddress {
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg MsgSubmitMisbehaviour) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
var misbehaviour exported.Misbehaviour
err := unpacker.UnpackAny(msg.Misbehaviour, &misbehaviour)
if err != nil {
return err
}
return nil
return unpacker.UnpackAny(msg.Misbehaviour, &misbehaviour)
}

View File

@ -56,7 +56,7 @@ func (suite *TypesTestSuite) TestMarshalMsgCreateClient() {
},
{
"tendermint client", func() {
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false)
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
msg, err = types.NewMsgCreateClient("tendermint", tendermintClient, suite.chainA.CreateTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
@ -108,7 +108,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() {
{
"valid - tendermint client",
func() {
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false)
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
msg, err = types.NewMsgCreateClient("tendermint", tendermintClient, suite.chainA.CreateTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
@ -132,7 +132,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() {
{
"failed to unpack consensus state",
func() {
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false)
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
msg, err = types.NewMsgCreateClient("tendermint", tendermintClient, suite.chainA.CreateTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
msg.ConsensusState = nil
@ -333,6 +333,133 @@ func (suite *TypesTestSuite) TestMsgUpdateClient_ValidateBasic() {
}
}
func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() {
var (
msg *types.MsgUpgradeClient
err error
)
testCases := []struct {
name string
malleate func()
}{
{
"client upgrades to new tendermint client",
func() {
tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
msg, err = types.NewMsgUpgradeClient("clientid", tendermintClient, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
},
{
"client upgrades to new solomachine client",
func() {
soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 1)
msg, err = types.NewMsgUpgradeClient("clientid", soloMachine.ClientState(), []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress())
suite.Require().NoError(err)
},
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
suite.SetupTest()
tc.malleate()
cdc := suite.chainA.App.AppCodec()
// marshal message
bz, err := cdc.MarshalJSON(msg)
suite.Require().NoError(err)
// unmarshal message
newMsg := &types.MsgUpgradeClient{}
err = cdc.UnmarshalJSON(bz, newMsg)
suite.Require().NoError(err)
suite.Require().True(proto.Equal(msg, newMsg))
})
}
}
func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() {
cases := []struct {
name string
malleate func(*types.MsgUpgradeClient)
expPass bool
}{
{
name: "success",
malleate: func(msg *types.MsgUpgradeClient) {},
expPass: true,
},
{
name: "client id empty",
malleate: func(msg *types.MsgUpgradeClient) {
msg.ClientId = ""
},
expPass: false,
},
{
name: "invalid client id",
malleate: func(msg *types.MsgUpgradeClient) {
msg.ClientId = "invalid~chain/id"
},
expPass: false,
},
{
name: "unpacking clientstate fails",
malleate: func(msg *types.MsgUpgradeClient) {
msg.ClientState = nil
},
expPass: false,
},
{
name: "invalid client state",
malleate: func(msg *types.MsgUpgradeClient) {
cs := &ibctmtypes.ClientState{}
var err error
msg.ClientState, err = types.PackClientState(cs)
suite.Require().NoError(err)
},
expPass: false,
},
{
name: "empty proof",
malleate: func(msg *types.MsgUpgradeClient) {
msg.ProofUpgrade = nil
},
expPass: false,
},
{
name: "empty signer",
malleate: func(msg *types.MsgUpgradeClient) {
msg.Signer = " "
},
expPass: false,
},
}
for _, tc := range cases {
tc := tc
clientState := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false)
msg, _ := types.NewMsgUpgradeClient("testclientid", clientState, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress())
tc.malleate(msg)
err := msg.ValidateBasic()
if tc.expPass {
suite.Require().NoError(err, "valid case %s failed", tc.name)
} else {
suite.Require().Error(err, "invalid case %s passed", tc.name)
}
}
}
// tests that different misbehaviours within MsgSubmitMisbehaviour can be marshaled
// and unmarshaled.
func (suite *TypesTestSuite) TestMarshalMsgSubmitMisbehaviour() {

View File

@ -107,7 +107,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() {
signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht")
clientState := ibctmtypes.NewClientState(
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false,
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false,
)
// Pack consensus state into any to test unpacking error
@ -119,7 +119,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() {
// invalidClientState fails validateBasic
invalidClient := ibctmtypes.NewClientState(
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false,
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false,
)
testMsgs := []*types.MsgConnectionOpenTry{
@ -179,7 +179,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() {
func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() {
signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht")
clientState := ibctmtypes.NewClientState(
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false,
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false,
)
// Pack consensus state into any to test unpacking error
@ -190,7 +190,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() {
// invalidClientState fails validateBasic
invalidClient := ibctmtypes.NewClientState(
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false,
chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false,
)
testMsgs := []*types.MsgConnectionOpenAck{

View File

@ -25,6 +25,7 @@ import (
const (
flagTrustLevel = "trust-level"
flagProofSpecs = "proof-specs"
flagUpgradePath = "upgrade-path"
flagAllowUpdateAfterExpiry = "allow_update_after_expiry"
flagAllowUpdateAfterMisbehaviour = "allow_update_after_misbehaviour"
)
@ -37,8 +38,10 @@ func NewCreateClientCmd() *cobra.Command {
Short: "create new tendermint client",
Long: `Create a new tendermint IBC client.
- 'trust-level' flag can be a fraction (eg: '1/3') or 'default'
- 'proof-specs' flag can be JSON input, a path to a .json file or 'default'`,
Example: fmt.Sprintf("%s tx ibc %s create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift] --trust-level default --proof-specs [path/to/proof-specs.json] --from node0 --home ../node0/<app>cli --chain-id $CID", version.AppName, types.SubModuleName),
- 'proof-specs' flag can be JSON input, a path to a .json file or 'default'
- 'upgrade-path' flag is a string specifying the upgrade path for this chain where a future upgraded client will be stored. The path represents a keypath for the store with each key separated by a '/'. Any slash within a key must be escaped.
e.g. 'upgrade/upgradedClient'`,
Example: fmt.Sprintf("%s tx ibc %s create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift] --trust-level default --proof-specs [path/to/proof-specs.json] --upgrade-path upgrade/upgradedClient --from node0 --home ../node0/<app>cli --chain-id $CID", version.AppName, types.SubModuleName),
Args: cobra.ExactArgs(5),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
@ -116,15 +119,24 @@ func NewCreateClientCmd() *cobra.Command {
allowUpdateAfterExpiry, _ := cmd.Flags().GetBool(flagAllowUpdateAfterExpiry)
allowUpdateAfterMisbehaviour, _ := cmd.Flags().GetBool(flagAllowUpdateAfterMisbehaviour)
upgradePath, _ := cmd.Flags().GetString(flagUpgradePath)
keyPath := strings.Split(upgradePath, "/")
if keyPath[0] == upgradePath {
return fmt.Errorf("invalid merkle path %s", upgradePath)
}
merklePath := commitmenttypes.NewMerklePath(keyPath)
// validate header
if err := header.ValidateBasic(); err != nil {
return err
}
height := header.GetHeight().(clienttypes.Height)
clientState := types.NewClientState(
header.GetHeader().GetChainID(), trustLevel, trustingPeriod, ubdPeriod, maxClockDrift,
height, specs, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour,
height, specs, &merklePath, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour,
)
consensusState := header.ConsensusState()

View File

@ -28,7 +28,7 @@ func NewClientState(
chainID string, trustLevel Fraction,
trustingPeriod, ubdPeriod, maxClockDrift time.Duration,
latestHeight clienttypes.Height, specs []*ics23.ProofSpec,
allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool,
upgradePath *commitmenttypes.MerklePath, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool,
) *ClientState {
return &ClientState{
ChainId: chainID,
@ -39,6 +39,7 @@ func NewClientState(
LatestHeight: latestHeight,
FrozenHeight: clienttypes.ZeroHeight(),
ProofSpecs: specs,
UpgradePath: upgradePath,
AllowUpdateAfterExpiry: allowUpdateAfterExpiry,
AllowUpdateAfterMisbehaviour: allowUpdateAfterMisbehaviour,
}
@ -121,6 +122,20 @@ func (cs ClientState) GetProofSpecs() []*ics23.ProofSpec {
return cs.ProofSpecs
}
// ZeroCustomFields returns a ClientState that is a copy of the current ClientState
// with all client customizable fields zeroed out
func (cs ClientState) ZeroCustomFields() exported.ClientState {
// copy over all chain-specified fields
// and leave custom fields empty
return &ClientState{
ChainId: cs.ChainId,
UnbondingPeriod: cs.UnbondingPeriod,
LatestHeight: cs.LatestHeight,
ProofSpecs: cs.ProofSpecs,
UpgradePath: cs.UpgradePath,
}
}
// VerifyClientState verifies a proof of the client state of the running chain
// stored on the target machine
func (cs ClientState) VerifyClientState(

View File

@ -32,52 +32,57 @@ func (suite *TendermintTestSuite) TestValidate() {
}{
{
name: "valid client",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: true,
},
{
name: "valid client with nil upgrade path",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), nil, false, false),
expPass: true,
},
{
name: "invalid chainID",
clientState: types.NewClientState(" ", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(" ", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "invalid trust level",
clientState: types.NewClientState(chainID, types.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "invalid trusting period",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "invalid unbonding period",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "invalid max clock drift",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "invalid height",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "trusting period not less than unbonding period",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
expPass: false,
},
{
name: "proof specs is nil",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil, false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil, &upgradePath, false, false),
expPass: false,
},
{
name: "proof specs contains nil",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}, false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}, &upgradePath, false, false),
expPass: false,
},
}
@ -113,7 +118,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
// },
{
name: "ApplyPrefix failed",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
consensusState: types.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
},
@ -122,7 +127,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
},
{
name: "latest client height < height",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
consensusState: types.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
},
@ -140,7 +145,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() {
},
{
name: "proof verification failed",
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
consensusState: types.ConsensusState{
Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()),
NextValidatorsHash: suite.valsHash,

View File

@ -53,7 +53,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
}{
{
"valid misbehavior misbehaviour",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -69,7 +69,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"valid misbehavior at height greater than last consensusState",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -85,7 +85,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"valid misbehaviour with different trusted heights",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -101,7 +101,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"valid misbehaviour at a previous epoch",
types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -117,7 +117,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"valid misbehaviour at a future epoch",
types.NewClientState(chainIDEpoch0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainIDEpoch0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -133,7 +133,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"valid misbehaviour with trusted heights at a previous epoch",
types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -149,7 +149,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"consensus state's valset hash different from misbehaviour should still pass",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -165,7 +165,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"invalid misbehavior misbehaviour from different chain",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -181,7 +181,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"invalid misbehavior misbehaviour with trusted height different from trusted consensus state",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -197,7 +197,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"invalid misbehavior misbehaviour with trusted validators different from trusted consensus state",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash),
@ -229,7 +229,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"trusted consensus state does not exist",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
nil, // consensus state for trusted height - 1 does not exist in store
clienttypes.Height{},
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -245,7 +245,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"invalid tendermint misbehaviour",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -256,7 +256,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"rejected misbehaviour due to expired age duration",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -272,7 +272,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"rejected misbehaviour due to expired block duration",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(0, uint64(epochHeight+simapp.DefaultConsensusParams.Evidence.MaxAgeNumBlocks+1)), commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(0, uint64(epochHeight+simapp.DefaultConsensusParams.Evidence.MaxAgeNumBlocks+1)), commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -288,7 +288,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"provided height > header height",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -304,7 +304,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"unbonding period expired",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(time.Time{}, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
heightMinus1,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -320,7 +320,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"trusted validators is incorrect for given consensus state",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -336,7 +336,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"first valset has too much change",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -352,7 +352,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"second valset has too much change",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
@ -368,7 +368,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() {
},
{
"both valsets have too much change",
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false),
types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false),
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),
height,
types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash),

View File

@ -51,12 +51,14 @@ type ClientState struct {
LatestHeight types.Height `protobuf:"bytes,7,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height" yaml:"latest_height"`
// Proof specifications used in verifying counterparty state
ProofSpecs []*_go.ProofSpec `protobuf:"bytes,8,rep,name=proof_specs,json=proofSpecs,proto3" json:"proof_specs,omitempty" yaml:"proof_specs"`
// Path at which next upgraded client will be committed
UpgradePath *types1.MerklePath `protobuf:"bytes,9,opt,name=upgrade_path,json=upgradePath,proto3" json:"upgrade_path,omitempty" yaml:"upgrade_path"`
// This flag, when set to true, will allow governance to recover a client
// which has expired
AllowUpdateAfterExpiry bool `protobuf:"varint,9,opt,name=allow_update_after_expiry,json=allowUpdateAfterExpiry,proto3" json:"allow_update_after_expiry,omitempty" yaml:"allow_update_after_expiry"`
AllowUpdateAfterExpiry bool `protobuf:"varint,10,opt,name=allow_update_after_expiry,json=allowUpdateAfterExpiry,proto3" json:"allow_update_after_expiry,omitempty" yaml:"allow_update_after_expiry"`
// This flag, when set to true, will allow governance to unfreeze a client
// whose chain has experienced a misbehaviour event
AllowUpdateAfterMisbehaviour bool `protobuf:"varint,10,opt,name=allow_update_after_misbehaviour,json=allowUpdateAfterMisbehaviour,proto3" json:"allow_update_after_misbehaviour,omitempty" yaml:"allow_update_after_misbehaviour"`
AllowUpdateAfterMisbehaviour bool `protobuf:"varint,11,opt,name=allow_update_after_misbehaviour,json=allowUpdateAfterMisbehaviour,proto3" json:"allow_update_after_misbehaviour,omitempty" yaml:"allow_update_after_misbehaviour"`
}
func (m *ClientState) Reset() { *m = ClientState{} }
@ -313,72 +315,74 @@ func init() {
func init() { proto.RegisterFile("ibc/tendermint/tendermint.proto", fileDescriptor_76a953d5a747dd66) }
var fileDescriptor_76a953d5a747dd66 = []byte{
// 1034 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x4f, 0x6f, 0xe3, 0xc4,
0x1b, 0xae, 0xdb, 0xfe, 0xda, 0x74, 0x92, 0xfe, 0xf9, 0xcd, 0x96, 0xae, 0x5b, 0xba, 0x71, 0x34,
0x20, 0x54, 0x21, 0xad, 0x4d, 0xb3, 0x2b, 0x90, 0x7a, 0xc3, 0x5d, 0x50, 0x8b, 0x58, 0xa9, 0xb8,
0x14, 0x10, 0x12, 0xb2, 0x1c, 0x7b, 0x92, 0x8c, 0x6a, 0x7b, 0x8c, 0x67, 0x52, 0x52, 0x3e, 0x01,
0x48, 0x1c, 0x56, 0x9c, 0xf6, 0xc0, 0x01, 0xbe, 0xcd, 0x1e, 0x7b, 0xe4, 0x64, 0x50, 0xfb, 0x0d,
0x72, 0xe4, 0x84, 0x3c, 0x33, 0xfe, 0x93, 0xb4, 0xd5, 0x2e, 0x97, 0x64, 0xe6, 0x7d, 0xde, 0xe7,
0x79, 0xe2, 0x77, 0xde, 0x79, 0x1d, 0x60, 0x90, 0x9e, 0x6f, 0x71, 0x1c, 0x07, 0x38, 0x8d, 0x48,
0xcc, 0x6b, 0x4b, 0x33, 0x49, 0x29, 0xa7, 0x70, 0x8d, 0xf4, 0x7c, 0xb3, 0x8a, 0xee, 0x74, 0xea,
0xc9, 0x97, 0x09, 0x66, 0xd6, 0x85, 0x17, 0x92, 0xc0, 0xe3, 0x34, 0x95, 0x8c, 0x9d, 0xdd, 0x5b,
0x19, 0xe2, 0x53, 0xa1, 0x0f, 0x7c, 0x1a, 0xf7, 0x09, 0xb5, 0x92, 0x94, 0xd2, 0x7e, 0x11, 0x6c,
0x0f, 0x28, 0x1d, 0x84, 0xd8, 0x12, 0xbb, 0xde, 0xa8, 0x6f, 0x05, 0xa3, 0xd4, 0xe3, 0x84, 0xc6,
0x0a, 0x37, 0x66, 0x71, 0x4e, 0x22, 0xcc, 0xb8, 0x17, 0x25, 0x2a, 0xe1, 0x61, 0xfe, 0x18, 0x7e,
0x48, 0x70, 0xcc, 0xd5, 0x57, 0xc1, 0x14, 0x00, 0x8d, 0x22, 0xc2, 0x23, 0x01, 0x96, 0x4b, 0x95,
0xb0, 0x39, 0xa0, 0x03, 0x2a, 0x96, 0x56, 0xbe, 0x92, 0x51, 0xf4, 0xcb, 0x32, 0x68, 0x1e, 0x0a,
0x9d, 0x53, 0xee, 0x71, 0x0c, 0xb7, 0x41, 0xc3, 0x1f, 0x7a, 0x24, 0x76, 0x49, 0xa0, 0x6b, 0x1d,
0x6d, 0x6f, 0xc5, 0x59, 0x16, 0xfb, 0xe3, 0x00, 0x9e, 0x81, 0x26, 0x4f, 0x47, 0x8c, 0xbb, 0x21,
0xbe, 0xc0, 0xa1, 0x3e, 0xdf, 0xd1, 0xf6, 0x9a, 0x5d, 0xdd, 0x9c, 0x2e, 0x9b, 0xf9, 0x69, 0xea,
0xf9, 0xf9, 0x03, 0xd9, 0x3b, 0xaf, 0x32, 0x63, 0x6e, 0x92, 0x19, 0xf0, 0xd2, 0x8b, 0xc2, 0x03,
0x54, 0xa3, 0x22, 0x07, 0x88, 0xdd, 0xe7, 0xf9, 0x06, 0xf6, 0xc1, 0xba, 0xd8, 0x91, 0x78, 0xe0,
0x26, 0x38, 0x25, 0x34, 0xd0, 0x17, 0x84, 0xf4, 0xb6, 0x29, 0x8b, 0x61, 0x16, 0xc5, 0x30, 0x9f,
0xa9, 0x62, 0xd9, 0x48, 0x69, 0x6f, 0xd5, 0xb4, 0x2b, 0x3e, 0x7a, 0xf9, 0x97, 0xa1, 0x39, 0x6b,
0x45, 0xf4, 0x44, 0x04, 0x21, 0x01, 0x1b, 0xa3, 0xb8, 0x47, 0xe3, 0xa0, 0x66, 0xb4, 0xf8, 0x3a,
0xa3, 0x77, 0x94, 0xd1, 0x43, 0x69, 0x34, 0x2b, 0x20, 0x9d, 0xd6, 0xcb, 0xb0, 0xb2, 0xc2, 0x60,
0x3d, 0xf2, 0xc6, 0xae, 0x1f, 0x52, 0xff, 0xdc, 0x0d, 0x52, 0xd2, 0xe7, 0xfa, 0xff, 0xfe, 0xe3,
0x23, 0xcd, 0xf0, 0xa5, 0xd1, 0x6a, 0xe4, 0x8d, 0x0f, 0xf3, 0xe0, 0xb3, 0x3c, 0x06, 0xcf, 0xc0,
0x6a, 0x3f, 0xa5, 0x3f, 0xe2, 0xd8, 0x1d, 0x62, 0x32, 0x18, 0x72, 0x7d, 0x49, 0x98, 0x40, 0x71,
0x24, 0xaa, 0x39, 0x8e, 0x04, 0x62, 0xef, 0x2a, 0xf5, 0x4d, 0xa9, 0x3e, 0x45, 0x43, 0x4e, 0x4b,
0xee, 0x65, 0x6e, 0x2e, 0x1b, 0x7a, 0x1c, 0x33, 0x5e, 0xc8, 0x2e, 0xbf, 0xa9, 0xec, 0x14, 0x0d,
0x39, 0x2d, 0xb9, 0x57, 0xb2, 0xc7, 0xa0, 0x29, 0xae, 0x82, 0xcb, 0x12, 0xec, 0x33, 0xbd, 0xd1,
0x59, 0xd8, 0x6b, 0x76, 0x37, 0x4c, 0xe2, 0xb3, 0xee, 0x13, 0xf3, 0x24, 0x47, 0x4e, 0x13, 0xec,
0xdb, 0x5b, 0x55, 0xcb, 0xd4, 0xd2, 0x91, 0x03, 0x92, 0x22, 0x85, 0x41, 0x17, 0x6c, 0x7b, 0x61,
0x48, 0x7f, 0x70, 0x47, 0x49, 0xe0, 0x71, 0xec, 0x7a, 0x7d, 0x8e, 0x53, 0x17, 0x8f, 0x13, 0x92,
0x5e, 0xea, 0x2b, 0x1d, 0x6d, 0xaf, 0x61, 0xbf, 0x3b, 0xc9, 0x8c, 0x8e, 0x94, 0xb9, 0x37, 0x15,
0x39, 0x5b, 0x02, 0x3b, 0x13, 0xd0, 0xc7, 0x39, 0xf2, 0x89, 0x00, 0xe0, 0xf7, 0xc0, 0xb8, 0x83,
0x15, 0x11, 0xd6, 0xc3, 0x43, 0xef, 0x82, 0xd0, 0x51, 0xaa, 0x03, 0x61, 0xf3, 0xfe, 0x24, 0x33,
0xde, 0xbb, 0xd7, 0xa6, 0x4e, 0x40, 0xce, 0xee, 0xac, 0xd9, 0xf3, 0x1a, 0x7c, 0xb0, 0xf8, 0xd3,
0xef, 0xc6, 0x1c, 0xfa, 0x6d, 0x1e, 0xac, 0x1d, 0xd2, 0x98, 0xe1, 0x98, 0x8d, 0x98, 0xbc, 0x91,
0x36, 0x58, 0x29, 0x87, 0x80, 0xb8, 0x92, 0xcd, 0xee, 0xce, 0xad, 0x36, 0xfa, 0xb2, 0xc8, 0xb0,
0x1b, 0xf9, 0x91, 0xbc, 0xc8, 0xbb, 0xa5, 0xa2, 0xc1, 0xa7, 0x60, 0x31, 0xa5, 0x94, 0xab, 0x3b,
0xbb, 0x23, 0x4f, 0xb2, 0x1a, 0x10, 0xcf, 0x71, 0x7a, 0x1e, 0x62, 0x87, 0x52, 0x6e, 0x2f, 0xe6,
0x74, 0x47, 0x64, 0xc3, 0x9f, 0x35, 0xb0, 0x19, 0xe3, 0x31, 0x77, 0xcb, 0xc1, 0xc7, 0xdc, 0xa1,
0xc7, 0x86, 0xe2, 0x7e, 0xb6, 0xec, 0xaf, 0x27, 0x99, 0xf1, 0xb6, 0x7c, 0xf6, 0xbb, 0xb2, 0xd0,
0x3f, 0x99, 0xf1, 0x74, 0x40, 0xf8, 0x70, 0xd4, 0xcb, 0xbd, 0xee, 0x9e, 0xbd, 0x56, 0x48, 0x7a,
0xcc, 0xea, 0x5d, 0x72, 0xcc, 0xcc, 0x23, 0x3c, 0xb6, 0xf3, 0x85, 0x03, 0x73, 0xb9, 0xaf, 0x4a,
0xb5, 0x23, 0x8f, 0x0d, 0x55, 0x79, 0xfe, 0x98, 0x07, 0xad, 0x7a, 0xd5, 0xe0, 0x3e, 0x58, 0x91,
0x1d, 0x59, 0xce, 0x2b, 0x7b, 0x73, 0x92, 0x19, 0x1b, 0xf2, 0x67, 0x95, 0x10, 0x72, 0x1a, 0x72,
0x7d, 0x1c, 0x40, 0xb3, 0x36, 0xe1, 0xe6, 0x05, 0xe3, 0xc1, 0x24, 0x33, 0xd6, 0x15, 0x43, 0x21,
0xa8, 0x1a, 0x7b, 0x5f, 0x80, 0xc6, 0x10, 0x7b, 0x01, 0x4e, 0xdd, 0x7d, 0x35, 0x98, 0xb6, 0x66,
0x67, 0xde, 0x91, 0xc0, 0xed, 0xf6, 0x75, 0x66, 0x2c, 0xcb, 0xf5, 0x7e, 0x25, 0x59, 0x90, 0x91,
0xb3, 0x2c, 0x97, 0xfb, 0x35, 0xc9, 0xae, 0x1a, 0x41, 0x6f, 0x20, 0xd9, 0xbd, 0x25, 0xd9, 0x2d,
0x25, 0xbb, 0x07, 0x8d, 0xbc, 0x3e, 0x2f, 0xf3, 0x1a, 0xfd, 0xba, 0x00, 0x96, 0x24, 0x03, 0x7a,
0x60, 0x95, 0x91, 0x41, 0x8c, 0x03, 0x57, 0xa6, 0xa9, 0xf6, 0x69, 0xd7, 0x8d, 0xe4, 0x2b, 0xeb,
0x54, 0xa4, 0x29, 0xd3, 0xdd, 0xab, 0xcc, 0xd0, 0xaa, 0x5b, 0x3d, 0x25, 0x81, 0x9c, 0x16, 0xab,
0xe5, 0xc2, 0xef, 0xc0, 0x6a, 0x79, 0xee, 0x2e, 0xc3, 0x45, 0x8b, 0xdd, 0x61, 0x51, 0x1e, 0xe8,
0x29, 0xe6, 0xb6, 0x5e, 0xc9, 0x4f, 0xd1, 0x91, 0xd3, 0xba, 0xa8, 0xe5, 0xc1, 0x6f, 0x80, 0x1c,
0xe3, 0xc2, 0x5f, 0x0c, 0xa3, 0x85, 0x7b, 0x87, 0xd1, 0x23, 0x35, 0x8c, 0xde, 0xaa, 0xbd, 0x14,
0x4a, 0x1e, 0x72, 0x56, 0x55, 0x40, 0x8d, 0xa3, 0x10, 0xc0, 0x22, 0xa3, 0x6a, 0x5c, 0x75, 0x1a,
0xaf, 0xfb, 0xf5, 0x8f, 0x26, 0x99, 0xb1, 0x3d, 0xed, 0x52, 0x69, 0x20, 0xe7, 0xff, 0x2a, 0x58,
0xb5, 0x30, 0xfa, 0x0c, 0x34, 0x8a, 0x17, 0x23, 0xdc, 0x05, 0x2b, 0xf1, 0x28, 0xc2, 0x69, 0x8e,
0x88, 0x13, 0x59, 0x70, 0xaa, 0x00, 0xec, 0x80, 0x66, 0x80, 0x63, 0x1a, 0x91, 0x58, 0xe0, 0xf3,
0x02, 0xaf, 0x87, 0xec, 0x93, 0x57, 0xd7, 0x6d, 0xed, 0xea, 0xba, 0xad, 0xfd, 0x7d, 0xdd, 0xd6,
0x5e, 0xdc, 0xb4, 0xe7, 0xae, 0x6e, 0xda, 0x73, 0x7f, 0xde, 0xb4, 0xe7, 0xbe, 0xfd, 0xb0, 0x76,
0xdd, 0x7c, 0xca, 0x22, 0xca, 0xd4, 0xd7, 0x63, 0x16, 0x9c, 0x5b, 0x63, 0x2b, 0xff, 0x8b, 0xf0,
0xc1, 0x47, 0x8f, 0x67, 0xff, 0xb6, 0xf4, 0x96, 0xc4, 0x1c, 0x79, 0xf2, 0x6f, 0x00, 0x00, 0x00,
0xff, 0xff, 0xf9, 0x7c, 0x92, 0x83, 0x24, 0x09, 0x00, 0x00,
// 1067 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcf, 0x6f, 0xe3, 0x44,
0x14, 0x6e, 0xda, 0xd2, 0xa6, 0x93, 0xf4, 0x07, 0xd3, 0xd2, 0xba, 0x25, 0x1b, 0x47, 0x06, 0xa1,
0x0a, 0x69, 0x1d, 0x9a, 0x5d, 0x81, 0xd4, 0x1b, 0xee, 0x82, 0x5a, 0xc4, 0x4a, 0xc5, 0xa5, 0x0b,
0x42, 0x42, 0xd6, 0xc4, 0x9e, 0xc4, 0xa3, 0xda, 0x1e, 0xe3, 0x99, 0x94, 0x94, 0xbf, 0x00, 0x6e,
0x2b, 0x4e, 0x7b, 0xe0, 0x00, 0xff, 0xcd, 0x1e, 0x7b, 0xe4, 0x64, 0x50, 0xcb, 0x5f, 0x90, 0x23,
0x27, 0xe4, 0x99, 0xf1, 0x8f, 0x64, 0x5b, 0xed, 0x72, 0x69, 0x67, 0xde, 0xf7, 0xbe, 0xef, 0xb3,
0xdf, 0xbc, 0x79, 0x0e, 0xd0, 0x49, 0xdf, 0xed, 0x72, 0x1c, 0x79, 0x38, 0x09, 0x49, 0xc4, 0x2b,
0x4b, 0x33, 0x4e, 0x28, 0xa7, 0x70, 0x8d, 0xf4, 0x5d, 0xb3, 0x8c, 0xee, 0x75, 0xaa, 0xc9, 0x57,
0x31, 0x66, 0xdd, 0x4b, 0x14, 0x10, 0x0f, 0x71, 0x9a, 0x48, 0xc6, 0x5e, 0xeb, 0x95, 0x0c, 0xf1,
0x57, 0xa1, 0x9b, 0x2e, 0x8d, 0x06, 0x84, 0x76, 0xe3, 0x84, 0xd2, 0x41, 0x1e, 0x6c, 0x0f, 0x29,
0x1d, 0x06, 0xb8, 0x2b, 0x76, 0xfd, 0xd1, 0xa0, 0xeb, 0x8d, 0x12, 0xc4, 0x09, 0x8d, 0x14, 0xae,
0xcf, 0xe2, 0x9c, 0x84, 0x98, 0x71, 0x14, 0xc6, 0x2a, 0x61, 0x27, 0x7b, 0x0d, 0x37, 0x20, 0x38,
0xe2, 0xea, 0x5f, 0xce, 0x14, 0x00, 0x0d, 0x43, 0xc2, 0x43, 0x01, 0x16, 0x4b, 0x95, 0xb0, 0x35,
0xa4, 0x43, 0x2a, 0x96, 0xdd, 0x6c, 0x25, 0xa3, 0xc6, 0x3f, 0xcb, 0xa0, 0x71, 0x24, 0x74, 0xce,
0x38, 0xe2, 0x18, 0xee, 0x82, 0xba, 0xeb, 0x23, 0x12, 0x39, 0xc4, 0xd3, 0x6a, 0x9d, 0xda, 0xfe,
0x8a, 0xbd, 0x2c, 0xf6, 0x27, 0x1e, 0x3c, 0x07, 0x0d, 0x9e, 0x8c, 0x18, 0x77, 0x02, 0x7c, 0x89,
0x03, 0x6d, 0xbe, 0x53, 0xdb, 0x6f, 0xf4, 0x34, 0x73, 0xba, 0x6c, 0xe6, 0xe7, 0x09, 0x72, 0xb3,
0x17, 0xb2, 0xf6, 0x5e, 0xa6, 0xfa, 0xdc, 0x24, 0xd5, 0xe1, 0x15, 0x0a, 0x83, 0x43, 0xa3, 0x42,
0x35, 0x6c, 0x20, 0x76, 0x5f, 0x66, 0x1b, 0x38, 0x00, 0xeb, 0x62, 0x47, 0xa2, 0xa1, 0x13, 0xe3,
0x84, 0x50, 0x4f, 0x5b, 0x10, 0xd2, 0xbb, 0xa6, 0x2c, 0x86, 0x99, 0x17, 0xc3, 0x7c, 0xa2, 0x8a,
0x65, 0x19, 0x4a, 0x7b, 0xbb, 0xa2, 0x5d, 0xf2, 0x8d, 0x17, 0x7f, 0xe9, 0x35, 0x7b, 0x2d, 0x8f,
0x9e, 0x8a, 0x20, 0x24, 0x60, 0x63, 0x14, 0xf5, 0x69, 0xe4, 0x55, 0x8c, 0x16, 0x5f, 0x67, 0xf4,
0x9e, 0x32, 0xda, 0x91, 0x46, 0xb3, 0x02, 0xd2, 0x69, 0xbd, 0x08, 0x2b, 0x2b, 0x0c, 0xd6, 0x43,
0x34, 0x76, 0xdc, 0x80, 0xba, 0x17, 0x8e, 0x97, 0x90, 0x01, 0xd7, 0xde, 0xfa, 0x9f, 0xaf, 0x34,
0xc3, 0x97, 0x46, 0xab, 0x21, 0x1a, 0x1f, 0x65, 0xc1, 0x27, 0x59, 0x0c, 0x9e, 0x83, 0xd5, 0x41,
0x42, 0x7f, 0xc2, 0x91, 0xe3, 0x63, 0x32, 0xf4, 0xb9, 0xb6, 0x24, 0x4c, 0xa0, 0x38, 0x12, 0xd5,
0x1c, 0xc7, 0x02, 0xb1, 0x5a, 0x4a, 0x7d, 0x4b, 0xaa, 0x4f, 0xd1, 0x0c, 0xbb, 0x29, 0xf7, 0x32,
0x37, 0x93, 0x0d, 0x10, 0xc7, 0x8c, 0xe7, 0xb2, 0xcb, 0x6f, 0x2a, 0x3b, 0x45, 0x33, 0xec, 0xa6,
0xdc, 0x2b, 0xd9, 0x13, 0xd0, 0x10, 0x57, 0xc1, 0x61, 0x31, 0x76, 0x99, 0x56, 0xef, 0x2c, 0xec,
0x37, 0x7a, 0x1b, 0x26, 0x71, 0x59, 0xef, 0x91, 0x79, 0x9a, 0x21, 0x67, 0x31, 0x76, 0xad, 0xed,
0xb2, 0x65, 0x2a, 0xe9, 0x86, 0x0d, 0xe2, 0x3c, 0x85, 0xc1, 0x67, 0xa0, 0x39, 0x8a, 0x87, 0x09,
0xf2, 0xb0, 0x13, 0x23, 0xee, 0x6b, 0x2b, 0xe2, 0x01, 0xf7, 0xe4, 0x03, 0x96, 0x7d, 0xff, 0x14,
0x27, 0x17, 0x01, 0x3e, 0x45, 0xdc, 0xb7, 0x76, 0x26, 0xa9, 0xbe, 0xa9, 0xce, 0xb0, 0xc2, 0x34,
0xec, 0x86, 0xda, 0x66, 0x59, 0xd0, 0x01, 0xbb, 0x28, 0x08, 0xe8, 0x8f, 0xce, 0x28, 0xf6, 0x10,
0xc7, 0x0e, 0x1a, 0x70, 0x9c, 0x38, 0x78, 0x1c, 0x93, 0xe4, 0x4a, 0x03, 0x9d, 0xda, 0x7e, 0xdd,
0x7a, 0x7f, 0x92, 0xea, 0x1d, 0x29, 0x74, 0x6f, 0xaa, 0x61, 0x6f, 0x0b, 0xec, 0x5c, 0x40, 0x9f,
0x66, 0xc8, 0x67, 0x02, 0x80, 0x3f, 0x00, 0xfd, 0x0e, 0x56, 0x48, 0x58, 0x1f, 0xfb, 0xe8, 0x92,
0xd0, 0x51, 0xa2, 0x35, 0x84, 0xcd, 0x87, 0x93, 0x54, 0xff, 0xe0, 0x5e, 0x9b, 0x2a, 0xc1, 0xb0,
0x5b, 0xb3, 0x66, 0x4f, 0x2b, 0xf0, 0xe1, 0xe2, 0xcf, 0xbf, 0xeb, 0x73, 0xc6, 0x6f, 0xf3, 0x60,
0xed, 0x88, 0x46, 0x0c, 0x47, 0x6c, 0xc4, 0xe4, 0x4d, 0xb7, 0xc0, 0x4a, 0x31, 0x5c, 0xc4, 0x55,
0xcf, 0x2a, 0x38, 0xdb, 0x9e, 0x5f, 0xe7, 0x19, 0x56, 0x3d, 0x3b, 0xea, 0xe7, 0x59, 0x17, 0x96,
0x34, 0xf8, 0x18, 0x2c, 0x26, 0x94, 0x72, 0x35, 0x0b, 0xee, 0x39, 0x00, 0x9b, 0x52, 0x6e, 0x2d,
0x66, 0x74, 0x5b, 0x64, 0xc3, 0x5f, 0x6a, 0x60, 0x2b, 0xc2, 0x63, 0xee, 0x14, 0x03, 0x95, 0x39,
0x3e, 0x62, 0xbe, 0xb8, 0xf7, 0x4d, 0xeb, 0x9b, 0x49, 0xaa, 0xbf, 0x2b, 0xdf, 0xfd, 0xae, 0x2c,
0xe3, 0xdf, 0x54, 0x7f, 0x3c, 0x24, 0xdc, 0x1f, 0xf5, 0x33, 0xaf, 0xbb, 0x67, 0x7a, 0x37, 0x20,
0x7d, 0xd6, 0xed, 0x5f, 0x71, 0xcc, 0xcc, 0x63, 0x3c, 0xb6, 0xb2, 0x85, 0x0d, 0x33, 0xb9, 0x67,
0x85, 0xda, 0x31, 0x62, 0xbe, 0x2a, 0xcf, 0x1f, 0xf3, 0xa0, 0x59, 0xad, 0x1a, 0x3c, 0x00, 0x2b,
0xb2, 0xd3, 0x8b, 0x39, 0x68, 0x6d, 0x4d, 0x52, 0x7d, 0x43, 0x3e, 0x56, 0x01, 0x19, 0x76, 0x5d,
0xae, 0x4f, 0x3c, 0x68, 0x56, 0x26, 0xe7, 0xbc, 0x60, 0x6c, 0x4e, 0x52, 0x7d, 0x5d, 0x31, 0x14,
0x62, 0x94, 0xe3, 0xf4, 0x2b, 0x50, 0xf7, 0x31, 0xf2, 0x70, 0xe2, 0x1c, 0xa8, 0x81, 0xb7, 0x3d,
0x3b, 0x4b, 0x8f, 0x05, 0x6e, 0xb5, 0x6f, 0x52, 0x7d, 0x59, 0xae, 0x0f, 0x4a, 0xc9, 0x9c, 0x6c,
0xd8, 0xcb, 0x72, 0x79, 0x50, 0x91, 0xec, 0xa9, 0xd1, 0xf6, 0x06, 0x92, 0xbd, 0x57, 0x24, 0x7b,
0x85, 0x64, 0xef, 0xb0, 0x9e, 0xd5, 0xe7, 0x45, 0x56, 0xa3, 0x5f, 0x17, 0xc0, 0x92, 0x64, 0x40,
0x04, 0x56, 0x19, 0x19, 0x46, 0xd8, 0x73, 0x64, 0x9a, 0x6a, 0x9f, 0x76, 0xd5, 0x48, 0x7e, 0x0a,
0xcf, 0x44, 0x9a, 0x32, 0x6d, 0x5d, 0xa7, 0x7a, 0xad, 0x9c, 0x16, 0x53, 0x12, 0x86, 0xdd, 0x64,
0x95, 0x5c, 0xf8, 0x3d, 0x58, 0x2d, 0xce, 0xdd, 0x61, 0x38, 0x6f, 0xb1, 0x3b, 0x2c, 0x8a, 0x03,
0x3d, 0xc3, 0xdc, 0xd2, 0x4a, 0xf9, 0x29, 0xba, 0x61, 0x37, 0x2f, 0x2b, 0x79, 0xf0, 0x5b, 0x20,
0x3f, 0x0f, 0xc2, 0x5f, 0x0c, 0xb9, 0x85, 0x7b, 0x87, 0xdc, 0x03, 0x35, 0xe4, 0xde, 0xa9, 0x7c,
0x6c, 0x0a, 0x9e, 0x61, 0xaf, 0xaa, 0x80, 0x1a, 0x73, 0x01, 0x80, 0x79, 0x46, 0xd9, 0xb8, 0xea,
0x34, 0x5e, 0xf7, 0xf4, 0x0f, 0x26, 0xa9, 0xbe, 0x3b, 0xed, 0x52, 0x6a, 0x18, 0xf6, 0xdb, 0x2a,
0x58, 0xb6, 0xb0, 0xf1, 0x05, 0xa8, 0xe7, 0x1f, 0x5c, 0xd8, 0x02, 0x2b, 0xd1, 0x28, 0xc4, 0x49,
0x86, 0x88, 0x13, 0x59, 0xb0, 0xcb, 0x00, 0xec, 0x80, 0x86, 0x87, 0x23, 0x1a, 0x92, 0x48, 0xe0,
0xf3, 0x02, 0xaf, 0x86, 0xac, 0xd3, 0x97, 0x37, 0xed, 0xda, 0xf5, 0x4d, 0xbb, 0xf6, 0xf7, 0x4d,
0xbb, 0xf6, 0xfc, 0xb6, 0x3d, 0x77, 0x7d, 0xdb, 0x9e, 0xfb, 0xf3, 0xb6, 0x3d, 0xf7, 0xdd, 0xc7,
0x95, 0xeb, 0xe6, 0x52, 0x16, 0x52, 0xa6, 0xfe, 0x3d, 0x64, 0xde, 0x45, 0x77, 0xdc, 0xcd, 0x7e,
0x7a, 0x7c, 0xf4, 0xc9, 0xc3, 0xd9, 0x9f, 0x43, 0xfd, 0x25, 0x31, 0x47, 0x1e, 0xfd, 0x17, 0x00,
0x00, 0xff, 0xff, 0x0a, 0x9b, 0x13, 0xaa, 0x7c, 0x09, 0x00, 0x00,
}
func (m *ClientState) Marshal() (dAtA []byte, err error) {
@ -409,7 +413,7 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0
}
i--
dAtA[i] = 0x50
dAtA[i] = 0x58
}
if m.AllowUpdateAfterExpiry {
i--
@ -419,7 +423,19 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0
}
i--
dAtA[i] = 0x48
dAtA[i] = 0x50
}
if m.UpgradePath != nil {
{
size, err := m.UpgradePath.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTendermint(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x4a
}
if len(m.ProofSpecs) > 0 {
for iNdEx := len(m.ProofSpecs) - 1; iNdEx >= 0; iNdEx-- {
@ -455,29 +471,29 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
}
i--
dAtA[i] = 0x32
n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):])
if err3 != nil {
return 0, err3
}
i -= n3
i = encodeVarintTendermint(dAtA, i, uint64(n3))
i--
dAtA[i] = 0x2a
n4, err4 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):])
n4, err4 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):])
if err4 != nil {
return 0, err4
}
i -= n4
i = encodeVarintTendermint(dAtA, i, uint64(n4))
i--
dAtA[i] = 0x22
n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):])
dAtA[i] = 0x2a
n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):])
if err5 != nil {
return 0, err5
}
i -= n5
i = encodeVarintTendermint(dAtA, i, uint64(n5))
i--
dAtA[i] = 0x22
n6, err6 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):])
if err6 != nil {
return 0, err6
}
i -= n6
i = encodeVarintTendermint(dAtA, i, uint64(n6))
i--
dAtA[i] = 0x1a
{
size, err := m.TrustLevel.MarshalToSizedBuffer(dAtA[:i])
@ -536,12 +552,12 @@ func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
}
i--
dAtA[i] = 0x12
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err8 != nil {
return 0, err8
n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err9 != nil {
return 0, err9
}
i -= n8
i = encodeVarintTendermint(dAtA, i, uint64(n8))
i -= n9
i = encodeVarintTendermint(dAtA, i, uint64(n9))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
@ -749,6 +765,10 @@ func (m *ClientState) Size() (n int) {
n += 1 + l + sovTendermint(uint64(l))
}
}
if m.UpgradePath != nil {
l = m.UpgradePath.Size()
n += 1 + l + sovTendermint(uint64(l))
}
if m.AllowUpdateAfterExpiry {
n += 2
}
@ -1138,6 +1158,42 @@ func (m *ClientState) Unmarshal(dAtA []byte) error {
}
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field UpgradePath", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTendermint
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTendermint
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTendermint
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.UpgradePath == nil {
m.UpgradePath = &types1.MerklePath{}
}
if err := m.UpgradePath.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 10:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field AllowUpdateAfterExpiry", wireType)
}
@ -1157,7 +1213,7 @@ func (m *ClientState) Unmarshal(dAtA []byte) error {
}
}
m.AllowUpdateAfterExpiry = bool(v != 0)
case 10:
case 11:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field AllowUpdateAfterMisbehaviour", wireType)
}

View File

@ -15,8 +15,10 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
ibctestingmock "github.com/cosmos/cosmos-sdk/x/ibc/testing/mock"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
const (
@ -29,7 +31,11 @@ const (
maxClockDrift time.Duration = time.Second * 10
)
var height = clienttypes.NewHeight(0, 4)
var (
height = clienttypes.NewHeight(0, 4)
upgradeHeight = clienttypes.NewHeight(1, 1)
upgradePath = commitmenttypes.NewMerklePath([]string{"upgrade", upgradetypes.KeyUpgradedClient})
)
type TendermintTestSuite struct {
suite.Suite

View File

@ -57,7 +57,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "successful update with next height and same validator set",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.headerTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now
@ -67,7 +67,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "successful update with future height and different validator set",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus5, height, suite.headerTime, bothValSet, suite.valSet, bothSigners)
currentTime = suite.now
@ -77,7 +77,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "successful update with next height and different validator set",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash())
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.headerTime, bothValSet, bothValSet, bothSigners)
currentTime = suite.now
@ -87,7 +87,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "successful update for a previous height",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
consStateHeight = heightMinus3
newHeader = types.CreateTestHeader(chainID, heightMinus1, heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners)
@ -98,7 +98,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "successful update for a previous epoch",
setup: func() {
clientState = types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainIDEpoch0, height, heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners)
currentTime = suite.now
@ -108,7 +108,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update with incorrect header chain-id",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader("ethermint", heightPlus1, height, suite.headerTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now
@ -118,7 +118,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update to a future epoch",
setup: func() {
clientState = types.NewClientState(chainIDEpoch0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainIDEpoch0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainIDEpoch1, clienttypes.NewHeight(1, 1), height, suite.headerTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now
@ -128,7 +128,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update: header height epoch and trusted height epoch mismatch",
setup: func() {
clientState = types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainIDEpoch1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainIDEpoch1, clienttypes.NewHeight(1, 3), height, suite.headerTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now
@ -138,7 +138,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update with next height: update header mismatches nextValSetHash",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.headerTime, bothValSet, suite.valSet, bothSigners)
currentTime = suite.now
@ -148,7 +148,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update with next height: update header mismatches different nextValSetHash",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash())
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.headerTime, suite.valSet, bothValSet, signers)
currentTime = suite.now
@ -158,7 +158,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update with future height: too much change in validator set",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus5, height, suite.headerTime, altValSet, suite.valSet, altSigners)
currentTime = suite.now
@ -168,7 +168,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus5, height, suite.headerTime, bothValSet, bothValSet, bothSigners)
currentTime = suite.now
@ -178,7 +178,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update: trusting period has passed since last client timestamp",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.headerTime, suite.valSet, suite.valSet, signers)
// make current time pass trusting period from last timestamp on clientstate
@ -189,7 +189,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update: header timestamp is past current timestamp",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers)
currentTime = suite.now
@ -199,7 +199,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "unsuccessful update: header timestamp is not past last client timestamp",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.clientTime, suite.valSet, suite.valSet, signers)
currentTime = suite.now
@ -209,7 +209,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "header basic validation failed",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
newHeader = types.CreateTestHeader(chainID, heightPlus1, height, suite.headerTime, suite.valSet, suite.valSet, signers)
// cause new header to fail validatebasic by changing commit height to mismatch header height
@ -221,7 +221,7 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() {
{
name: "header height < consensus height",
setup: func() {
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, heightPlus5, commitmenttypes.GetSDKSpecs(), false, false)
clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, heightPlus5, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash)
// Make new header at height less than latest client state
newHeader = types.CreateTestHeader(chainID, heightMinus1, height, suite.headerTime, suite.valSet, suite.valSet, signers)

View File

@ -0,0 +1,58 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/ibc/exported"
)
// VerifyUpgrade checks if the upgraded client has been committed by the current client
// It will zero out all client-specific fields (e.g. TrustingPeriod and verify all data
// in client state that must be the same across all valid Tendermint clients for the new chain.
// VerifyUpgrade will return an error if:
// - the upgradedClient is not a Tendermint ClientState
// - the height of upgraded client is not greater than that of current client
// - the latest height of the new client does not match the height in committed client
// - any Tendermint chain specified parameter in upgraded client such as ChainID, UnbondingPeriod,
// and ProofSpecs do not match parameters set by committed client
func (cs ClientState) VerifyUpgrade(
ctx sdk.Context, cdc codec.BinaryMarshaler, clientStore sdk.KVStore,
upgradedClient exported.ClientState, proofUpgrade []byte,
) error {
if cs.UpgradePath == nil {
return sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, no upgrade path set")
}
if !upgradedClient.GetLatestHeight().GT(cs.GetLatestHeight()) {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgrade client height %s must be greater than current client height %s",
upgradedClient.GetLatestHeight(), cs.GetLatestHeight())
}
if len(proofUpgrade) == 0 {
return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "proof of upgrade is empty")
}
var merkleProof commitmenttypes.MerkleProof
if err := cdc.UnmarshalBinaryBare(proofUpgrade, &merkleProof); err != nil {
return sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal merkle proof: %v", err)
}
// counterparty chain must commit the upgraded client with all client-customizable fields zeroed out
// at the upgrade path specified by current client
committedClient := upgradedClient.ZeroCustomFields()
bz, err := codec.MarshalAny(cdc, committedClient)
if err != nil {
return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err)
}
// Must prove against latest consensus state to ensure we are verifying against latest upgrade plan
consState, err := GetConsensusState(clientStore, cdc, cs.GetLatestHeight())
if err != nil {
return sdkerrors.Wrap(err, "could not retrieve latest consensus state")
}
return merkleProof.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), *cs.UpgradePath, bz)
}

View File

@ -0,0 +1,276 @@
package types_test
import (
"github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/ibc/exported"
solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/solomachine/types"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
func (suite *TendermintTestSuite) TestVerifyUpgrade() {
var (
upgradedClient exported.ClientState
clientA string
proofUpgrade []byte
)
testCases := []struct {
name string
setup func()
expPass bool
}{
{
name: "successful upgrade to a new tendermint client",
setup: func() {
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: true,
},
{
name: "successful upgrade to a new tendermint client with different client chosen parameters",
setup: func() {
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// change upgradedClient client-specified parameters
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, true, true)
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: true,
},
{
name: "successful upgrade to a solomachine client",
setup: func() {
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
// demonstrate that VerifyUpgrade allows for arbitrary changes to clienstate structure so long as
// previous chain committed to the change
upgradedClient = ibctesting.NewSolomachine(suite.T(), suite.cdc, clientA, "diversifier", 1).ClientState()
soloClient, _ := upgradedClient.(*solomachinetypes.ClientState)
// change sequence to be higher height than latest current client height
soloClient.Sequence = cs.GetLatestHeight().GetEpochHeight() + 100
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found = suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: true,
},
{
name: "successful upgrade to a solomachine client with different client-chosen parameters",
setup: func() {
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
// demonstrate that VerifyUpgrade allows for arbitrary changes to clienstate structure so long as
// previous chain committed to the change
upgradedClient = ibctesting.NewSolomachine(suite.T(), suite.cdc, clientA, "diversifier", 1).ClientState()
soloClient, _ := upgradedClient.(*solomachinetypes.ClientState)
// change sequence to be higher height than latest current client height
soloClient.Sequence = cs.GetLatestHeight().GetEpochHeight() + 100
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), soloClient)
// change client-specified parameter
soloClient.AllowUpdateAfterProposal = true
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found = suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: true,
},
{
name: "unsuccessful upgrade to a new tendermint client: chain-specified paramaters do not match committed client",
setup: func() {
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// change upgradedClient client-specified parameters
upgradedClient = types.NewClientState("wrongchainID", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, true, true)
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: false,
},
{
name: "unsuccessful upgrade to a new solomachine client: chain-specified paramaters do not match committed client",
setup: func() {
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
// demonstrate that VerifyUpgrade allows for arbitrary changes to clienstate structure so long as
// previous chain committed to the change
upgradedClient = ibctesting.NewSolomachine(suite.T(), suite.cdc, clientA, "diversifier", 1).ClientState()
soloClient, _ := upgradedClient.(*solomachinetypes.ClientState)
// change sequence to be higher height than latest current client height
soloClient.Sequence = cs.GetLatestHeight().GetEpochHeight() + 100
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// change chain-specified parameters from committed values
soloClient.Sequence = 10000
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found = suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: false,
},
{
name: "unsuccessful upgrade to a new tendermint client: proof is empty",
setup: func() {
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
proofUpgrade = []byte{}
},
expPass: false,
},
{
name: "unsuccessful upgrade to a new tendermint client: proof unmarshal failed",
setup: func() {
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
proofUpgrade = []byte("proof")
},
expPass: false,
},
{
name: "unsuccessful upgrade to a new tendermint client: proof verification failed",
setup: func() {
// create but do not store upgraded client
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: false,
},
{
name: "unsuccessful upgrade to a new tendermint client: upgrade path is nil",
setup: func() {
upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), &upgradePath, false, false)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
// SetClientState with nil upgrade path
tmClient, _ := cs.(*types.ClientState)
tmClient.UpgradePath = nil
suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, tmClient)
},
expPass: false,
},
{
name: "unsuccessful upgrade to a new tendermint client: 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)
// zero custom fields and store in upgrade store
suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), upgradedClient)
// commit upgrade store changes and update clients
suite.coordinator.CommitBlock(suite.chainB)
err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, ibctesting.Tendermint)
suite.Require().NoError(err)
cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA)
suite.Require().True(found)
proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(), cs.GetLatestHeight().GetEpochHeight())
},
expPass: false,
},
}
for _, tc := range testCases {
tc := tc
clientA, _ = suite.coordinator.SetupClients(suite.chainA, suite.chainB, ibctesting.Tendermint)
tc.setup()
cs := suite.chainA.GetClientState(clientA)
clientStore := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA)
err := cs.VerifyUpgrade(
suite.chainA.GetContext(),
suite.cdc,
clientStore,
upgradedClient,
proofUpgrade,
)
if tc.expPass {
suite.Require().NoError(err, "verify upgrade failed on valid case: %s", tc.name)
} else {
suite.Require().Error(err, "verify upgrade passed on invalid case: %s", tc.name)
}
}
}

View File

@ -69,6 +69,11 @@ func (cs ClientState) GetProofSpecs() []*ics23.ProofSpec {
return nil
}
// ZeroCustomFields returns the same client state since there are no custom fields in localhost
func (cs ClientState) ZeroCustomFields() exported.ClientState {
return &cs
}
// CheckHeaderAndUpdateState updates the localhost client. It only needs access to the context
func (cs *ClientState) CheckHeaderAndUpdateState(
ctx sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, _ exported.Header,
@ -97,6 +102,14 @@ func (cs ClientState) CheckProposedHeaderAndUpdateState(
return nil, nil, sdkerrors.Wrap(clienttypes.ErrUpdateClientFailed, "cannot update localhost client with a proposal")
}
// VerifyUpgrade returns an error since localhost cannot be upgraded
func (cs ClientState) VerifyUpgrade(
_ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore,
_ exported.ClientState, _ []byte,
) error {
return sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade localhost client")
}
// VerifyClientState verifies that the localhost client state is stored locally
func (cs ClientState) VerifyClientState(
store sdk.KVStore, cdc codec.BinaryMarshaler, _ exported.Root,

View File

@ -44,6 +44,10 @@ var KeyEncoding_value = map[string]int32{
"KEY_ENCODING_HEX": 1,
}
func (x KeyEncoding) String() string {
return proto.EnumName(KeyEncoding_name, int32(x))
}
func (KeyEncoding) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_71f36b3839a24c54, []int{0}
}
@ -266,8 +270,8 @@ var xxx_messageInfo_KeyPath proto.InternalMessageInfo
// Key defines a proof Key
type Key struct {
name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
enc KeyEncoding `protobuf:"varint,2,opt,name=enc,proto3,enum=ibc.commitment.KeyEncoding" json:"enc,omitempty"`
Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Enc KeyEncoding `protobuf:"varint,2,opt,name=enc,proto3,enum=ibc.commitment.KeyEncoding" json:"enc,omitempty"`
}
func (m *Key) Reset() { *m = Key{} }
@ -316,39 +320,38 @@ func init() {
func init() { proto.RegisterFile("ibc/commitment/commitment.proto", fileDescriptor_71f36b3839a24c54) }
var fileDescriptor_71f36b3839a24c54 = []byte{
// 506 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xc1, 0x6e, 0xd3, 0x4c,
0x10, 0xc7, 0xed, 0x2f, 0xfe, 0x48, 0xd8, 0x54, 0x25, 0x2c, 0xa0, 0x46, 0x69, 0x6b, 0x47, 0x3e,
0x40, 0x40, 0xaa, 0x2d, 0x52, 0xd4, 0x43, 0xc4, 0x01, 0xa5, 0x31, 0x34, 0x4a, 0x49, 0xa3, 0x45,
0x91, 0x0a, 0x17, 0xcb, 0x71, 0x36, 0xb1, 0xe5, 0xda, 0x6b, 0xd9, 0x8b, 0x54, 0xbf, 0x41, 0xc5,
0x89, 0x23, 0x17, 0x24, 0x24, 0x38, 0xf0, 0x28, 0x3d, 0xf6, 0xc8, 0xc9, 0x42, 0xce, 0x1b, 0xf4,
0x09, 0xd0, 0xee, 0xa6, 0x4a, 0x2a, 0xf5, 0xb2, 0x9e, 0xf5, 0xfc, 0x3c, 0xf3, 0x9f, 0xbf, 0x07,
0x68, 0xfe, 0xc4, 0x35, 0x5d, 0x12, 0x86, 0x3e, 0x0d, 0x71, 0x44, 0xd7, 0x42, 0x23, 0x4e, 0x08,
0x25, 0x70, 0xd3, 0x9f, 0xb8, 0xc6, 0xea, 0x6d, 0xe3, 0xf1, 0x9c, 0xcc, 0x09, 0x4f, 0x99, 0x2c,
0x12, 0x54, 0x63, 0x97, 0xe2, 0x68, 0x8a, 0x93, 0xd0, 0x67, 0x25, 0x92, 0x2c, 0xa6, 0xc4, 0x8c,
0x13, 0x42, 0x66, 0x22, 0xad, 0x3f, 0x05, 0xe0, 0x3d, 0x4e, 0x82, 0x33, 0x8c, 0x08, 0xa1, 0x10,
0x02, 0xc5, 0x73, 0x52, 0xaf, 0x2e, 0x37, 0xe5, 0xd6, 0x06, 0xe2, 0x71, 0x47, 0xb9, 0xf8, 0xa1,
0x49, 0x7a, 0x0f, 0x6c, 0x08, 0x6e, 0x94, 0xe0, 0x99, 0x7f, 0x0e, 0x5f, 0x01, 0x10, 0xe0, 0xcc,
0x8e, 0xf9, 0x4d, 0xf0, 0xdd, 0x27, 0xd7, 0xb9, 0xf6, 0x30, 0x73, 0xc2, 0xb3, 0x8e, 0xbe, 0xca,
0xe9, 0xe8, 0x7e, 0x80, 0x33, 0xf1, 0x95, 0x6e, 0xdf, 0x74, 0x1b, 0x39, 0xd4, 0x83, 0x03, 0x50,
0xe1, 0x9c, 0x43, 0x45, 0xc7, 0x6a, 0x7b, 0xcb, 0xb8, 0x3d, 0x93, 0x31, 0xc0, 0x19, 0x43, 0xbb,
0x5b, 0x97, 0xb9, 0x26, 0x5d, 0xe7, 0xda, 0x83, 0xb5, 0xf2, 0x0e, 0xf5, 0x74, 0x54, 0x0e, 0x04,
0xd1, 0x51, 0xbe, 0x31, 0x99, 0x6f, 0x40, 0xf5, 0x46, 0x26, 0x21, 0x33, 0xf8, 0x12, 0xfc, 0xcf,
0x87, 0x5d, 0x96, 0xdf, 0x36, 0x56, 0x66, 0x18, 0xc2, 0x0c, 0x83, 0x83, 0x27, 0x71, 0x8a, 0x04,
0xa9, 0xbf, 0x06, 0xe5, 0x65, 0x53, 0xf8, 0x0c, 0x28, 0x01, 0xce, 0xd2, 0xba, 0xdc, 0x2c, 0xb5,
0xaa, 0xed, 0x47, 0x77, 0x68, 0x43, 0x1c, 0xe8, 0x54, 0x98, 0x45, 0xbc, 0xbf, 0x03, 0x4a, 0x03,
0x9c, 0xc1, 0x1d, 0xa0, 0x44, 0x4e, 0x88, 0x97, 0xbe, 0x54, 0x8a, 0x5c, 0xe3, 0x77, 0xc4, 0x4f,
0x78, 0x00, 0x4a, 0x38, 0x72, 0xeb, 0xff, 0x35, 0xe5, 0xd6, 0x66, 0x7b, 0xfb, 0x8e, 0xb2, 0x56,
0xe4, 0x92, 0xa9, 0x1f, 0xcd, 0xbb, 0xe5, 0x22, 0xd7, 0x18, 0x8b, 0xd8, 0x21, 0xfe, 0xc4, 0x0b,
0x07, 0x54, 0xd7, 0x10, 0xf8, 0x1c, 0xec, 0x0c, 0xac, 0x8f, 0xb6, 0x35, 0x3c, 0x3c, 0xe9, 0xf5,
0x87, 0xef, 0xec, 0x31, 0x3a, 0xb6, 0xc7, 0xc3, 0x0f, 0x23, 0xeb, 0xb0, 0xff, 0xb6, 0x6f, 0xf5,
0x6a, 0x52, 0xa3, 0xfc, 0xe5, 0x7b, 0xb3, 0x34, 0x46, 0xc7, 0x70, 0x17, 0xd4, 0x6e, 0xa1, 0x47,
0xd6, 0x69, 0x4d, 0x16, 0xe9, 0x23, 0xeb, 0xb4, 0x51, 0xb9, 0xf8, 0xa9, 0x4a, 0xbf, 0x7f, 0xa9,
0x52, 0x77, 0x74, 0x59, 0xa8, 0xf2, 0x55, 0xa1, 0xca, 0x7f, 0x0b, 0x55, 0xfe, 0xba, 0x50, 0xa5,
0xab, 0x85, 0x2a, 0xfd, 0x59, 0xa8, 0xd2, 0xa7, 0x83, 0xb9, 0x4f, 0xbd, 0xcf, 0x13, 0xa6, 0xd7,
0x74, 0x49, 0x1a, 0x92, 0x74, 0xf9, 0xd8, 0x4b, 0xa7, 0x81, 0x79, 0x6e, 0xb2, 0x9d, 0x6d, 0xef,
0xef, 0xad, 0xad, 0x2d, 0xcd, 0x62, 0x9c, 0x4e, 0xee, 0xf1, 0x6d, 0xdb, 0xff, 0x17, 0x00, 0x00,
0xff, 0xff, 0xeb, 0x84, 0x9f, 0x36, 0xd5, 0x02, 0x00, 0x00,
// 486 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x51, 0x6b, 0xd3, 0x50,
0x14, 0xc7, 0x13, 0x1b, 0xed, 0x3c, 0x1d, 0xb3, 0x5e, 0x95, 0x95, 0xce, 0x25, 0x25, 0x0f, 0x5a,
0x85, 0x26, 0xd8, 0x89, 0x0f, 0xc5, 0x07, 0xe9, 0x1a, 0x5d, 0xe9, 0xec, 0x4a, 0xa4, 0x30, 0x05,
0x09, 0x69, 0x7a, 0xdb, 0x84, 0x2c, 0xb9, 0x21, 0xb9, 0xc2, 0xf2, 0x0d, 0x86, 0x4f, 0x3e, 0xfa,
0x22, 0x08, 0x7e, 0x99, 0x3d, 0xee, 0xd1, 0xa7, 0x22, 0xed, 0x37, 0xd8, 0x27, 0x90, 0x7b, 0x6f,
0x4b, 0x3b, 0xd8, 0x53, 0x4e, 0xf2, 0xff, 0xe5, 0x9c, 0xff, 0xf9, 0x73, 0x40, 0x0b, 0x46, 0x9e,
0xe9, 0x91, 0x28, 0x0a, 0x68, 0x84, 0x63, 0xba, 0x51, 0x1a, 0x49, 0x4a, 0x28, 0x41, 0x3b, 0xc1,
0xc8, 0x33, 0xd6, 0x5f, 0xab, 0x8f, 0xa7, 0x64, 0x4a, 0xb8, 0x64, 0xb2, 0x4a, 0x50, 0xd5, 0x7d,
0x8a, 0xe3, 0x31, 0x4e, 0xa3, 0x80, 0xb5, 0x48, 0xf3, 0x84, 0x12, 0x33, 0x49, 0x09, 0x99, 0x08,
0x59, 0x7f, 0x06, 0xf0, 0x11, 0xa7, 0xe1, 0x19, 0xb6, 0x09, 0xa1, 0x08, 0x81, 0xe2, 0xbb, 0x99,
0x5f, 0x91, 0x6b, 0x72, 0x7d, 0xdb, 0xe6, 0x75, 0x4b, 0xb9, 0xf8, 0xad, 0x49, 0x7a, 0x07, 0xb6,
0x05, 0x37, 0x48, 0xf1, 0x24, 0x38, 0x47, 0xaf, 0x01, 0x42, 0x9c, 0x3b, 0x09, 0x7f, 0x13, 0x7c,
0xfb, 0xc9, 0xf5, 0x4c, 0x7b, 0x98, 0xbb, 0xd1, 0x59, 0x4b, 0x5f, 0x6b, 0xba, 0x7d, 0x3f, 0xc4,
0xb9, 0xf8, 0x4b, 0x77, 0x56, 0xd3, 0x06, 0x2e, 0xf5, 0x51, 0x0f, 0xb6, 0x38, 0xe7, 0x52, 0x31,
0xb1, 0xd4, 0xdc, 0x35, 0x6e, 0xee, 0x64, 0xf4, 0x70, 0xce, 0xd0, 0xf6, 0xee, 0xe5, 0x4c, 0x93,
0xae, 0x67, 0xda, 0x83, 0x8d, 0xf6, 0x2e, 0xf5, 0x75, 0xbb, 0x18, 0x0a, 0xa2, 0xa5, 0xfc, 0x64,
0x36, 0xdf, 0x41, 0x69, 0x65, 0x93, 0x90, 0x09, 0x7a, 0x05, 0x77, 0xf9, 0xb2, 0xcb, 0xf6, 0x7b,
0xc6, 0x3a, 0x0c, 0x43, 0x84, 0x61, 0x70, 0xf0, 0x24, 0xc9, 0x6c, 0x41, 0xea, 0x6f, 0xa1, 0xb8,
0x1c, 0x8a, 0x9e, 0x83, 0x12, 0xe2, 0x3c, 0xab, 0xc8, 0xb5, 0x42, 0xbd, 0xd4, 0x7c, 0x74, 0x8b,
0x37, 0x9b, 0x03, 0xad, 0x2d, 0x16, 0x11, 0x9f, 0xdf, 0x87, 0x42, 0x0f, 0xe7, 0x2c, 0xc7, 0xd8,
0x8d, 0xf0, 0x2a, 0x47, 0x56, 0xa3, 0x06, 0x14, 0x70, 0xec, 0x55, 0xee, 0xd4, 0xe4, 0xfa, 0x4e,
0x73, 0xef, 0x96, 0x66, 0x56, 0xec, 0x91, 0x71, 0x10, 0x4f, 0x6d, 0xc6, 0x89, 0xd8, 0x5f, 0x7e,
0x85, 0xd2, 0x86, 0x82, 0x5e, 0xc0, 0xd3, 0x9e, 0xf5, 0xd9, 0xb1, 0xfa, 0x87, 0x27, 0x9d, 0x6e,
0xff, 0x83, 0x33, 0xb4, 0x8f, 0x9d, 0x61, 0xff, 0xd3, 0xc0, 0x3a, 0xec, 0xbe, 0xef, 0x5a, 0x9d,
0xb2, 0x54, 0x2d, 0x7e, 0xff, 0x55, 0x2b, 0x0c, 0xed, 0x63, 0xb4, 0x0f, 0xe5, 0x1b, 0xe8, 0x91,
0x75, 0x5a, 0x96, 0x85, 0x7c, 0x64, 0x9d, 0x56, 0x95, 0x8b, 0x3f, 0xaa, 0xd4, 0x1e, 0x5c, 0xce,
0x55, 0xf9, 0x6a, 0xae, 0xca, 0xff, 0xe6, 0xaa, 0xfc, 0x63, 0xa1, 0x4a, 0x57, 0x0b, 0x55, 0xfa,
0xbb, 0x50, 0xa5, 0x2f, 0x6f, 0xa6, 0x01, 0xf5, 0xbf, 0x8d, 0x98, 0x45, 0xd3, 0x23, 0x59, 0x44,
0xb2, 0xe5, 0xa3, 0x91, 0x8d, 0x43, 0xf3, 0xdc, 0x64, 0xc7, 0xd9, 0x3c, 0x68, 0x6c, 0xdc, 0x27,
0xcd, 0x13, 0x9c, 0x8d, 0xee, 0xf1, 0xb3, 0x3a, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xf2, 0xfd,
0xcd, 0x54, 0xbe, 0x02, 0x00, 0x00,
}
func (m *MerkleRoot) Marshal() (dAtA []byte, err error) {
@ -536,15 +539,15 @@ func (m *Key) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.enc != 0 {
i = encodeVarintCommitment(dAtA, i, uint64(m.enc))
if m.Enc != 0 {
i = encodeVarintCommitment(dAtA, i, uint64(m.Enc))
i--
dAtA[i] = 0x10
}
if len(m.name) > 0 {
i -= len(m.name)
copy(dAtA[i:], m.name)
i = encodeVarintCommitment(dAtA, i, uint64(len(m.name)))
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintCommitment(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
}
@ -633,12 +636,12 @@ func (m *Key) Size() (n int) {
}
var l int
_ = l
l = len(m.name)
l = len(m.Name)
if l > 0 {
n += 1 + l + sovCommitment(uint64(l))
}
if m.enc != 0 {
n += 1 + sovCommitment(uint64(m.enc))
if m.Enc != 0 {
n += 1 + sovCommitment(uint64(m.Enc))
}
return n
}
@ -1116,7 +1119,7 @@ func (m *Key) Unmarshal(dAtA []byte) error {
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field name", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
@ -1143,16 +1146,16 @@ func (m *Key) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.name = append(m.name[:0], dAtA[iNdEx:postIndex]...)
if m.name == nil {
m.name = []byte{}
m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...)
if m.Name == nil {
m.Name = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field enc", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Enc", wireType)
}
m.enc = 0
m.Enc = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCommitment
@ -1162,7 +1165,7 @@ func (m *Key) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.enc |= KeyEncoding(b&0x7F) << shift
m.Enc |= KeyEncoding(b&0x7F) << shift
if b < 0x80 {
break
}

View File

@ -7,7 +7,7 @@ import (
// AppendKey appends a new key to a KeyPath
func (pth KeyPath) AppendKey(key []byte, enc KeyEncoding) KeyPath {
pth.Keys = append(pth.Keys, &Key{name: key, enc: enc})
pth.Keys = append(pth.Keys, &Key{Name: key, Enc: enc})
return pth
}
@ -15,11 +15,11 @@ func (pth KeyPath) AppendKey(key []byte, enc KeyEncoding) KeyPath {
func (pth *KeyPath) String() string {
res := ""
for _, key := range pth.Keys {
switch key.enc {
switch key.Enc {
case URL:
res += "/" + url.PathEscape(string(key.name))
res += "/" + url.PathEscape(string(key.Name))
case HEX:
res += "/x:" + fmt.Sprintf("%X", key.name)
res += "/x:" + fmt.Sprintf("%X", key.Name)
default:
panic("unexpected key encoding type")
}
@ -36,5 +36,5 @@ func (pth *KeyPath) String() string {
func (pth *KeyPath) GetKey(i int) []byte {
total := len(pth.Keys)
index := (total + i) % total
return pth.Keys[index].name
return pth.Keys[index].Name
}

View File

@ -126,7 +126,7 @@ func (proof MerkleProof) VerifyMembership(specs []*ics23.ProofSpec, root exporte
// VerifyMembership specific argument validation
mpath, ok := path.(MerklePath)
if !ok {
return sdkerrors.Wrapf(ErrInvalidProof, "path %v is not of type MerkleProof", path)
return sdkerrors.Wrapf(ErrInvalidProof, "path %v is not of type MerklePath", path)
}
if len(mpath.KeyPath.Keys) != len(specs) {
return sdkerrors.Wrapf(ErrInvalidProof, "path length %d not same as proof %d",

View File

@ -32,6 +32,19 @@ type ClientState interface {
CheckMisbehaviourAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Misbehaviour) (ClientState, error)
CheckProposedHeaderAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Header) (ClientState, ConsensusState, error)
// Upgrade functions
VerifyUpgrade(
ctx sdk.Context,
cdc codec.BinaryMarshaler,
store sdk.KVStore,
newClient ClientState,
proofUpgrade []byte,
) error
// Utility function that zeroes out any client customizable fields in client state
// Ledger enforced fields are maintained while all custom fields are zero values
// Used to verify upgrades
ZeroCustomFields() ClientState
// State verification functions
VerifyClientState(

View File

@ -37,7 +37,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
ClientGenesis: clienttypes.NewGenesisState(
[]clienttypes.IdentifiedClientState{
clienttypes.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
clienttypes.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight),
@ -100,7 +100,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() {
ClientGenesis: clienttypes.NewGenesisState(
[]clienttypes.IdentifiedClientState{
clienttypes.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
clienttypes.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("(chaindID)", clienttypes.ZeroHeight()),
@ -169,7 +169,7 @@ func (suite *IBCTestSuite) TestInitGenesis() {
ClientGenesis: clienttypes.NewGenesisState(
[]clienttypes.IdentifiedClientState{
clienttypes.NewIdentifiedClientState(
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), false, false),
clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), &ibctesting.UpgradePath, false, false),
),
clienttypes.NewIdentifiedClientState(
exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight),

View File

@ -68,6 +68,22 @@ func (cs ClientState) Validate() error {
return cs.ConsensusState.ValidateBasic()
}
// ZeroCustomFields returns solomachine client state with client-specific fields FrozenSequence,
// and AllowUpdateAfterProposal zeroed out
func (cs ClientState) ZeroCustomFields() exported.ClientState {
return NewClientState(
cs.Sequence, cs.ConsensusState, false,
)
}
// VerifyUpgrade returns an error since solomachine client does not support upgrades
func (cs ClientState) VerifyUpgrade(
_ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore,
_ exported.ClientState, _ []byte,
) error {
return sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade solomachine client")
}
// VerifyClientState verifies a proof of the client state of the running chain
// stored on the solo machine.
func (cs ClientState) VerifyClientState(

View File

@ -37,6 +37,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/ibc/testing/mock"
"github.com/cosmos/cosmos-sdk/x/ibc/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
const (
@ -69,6 +70,8 @@ var (
TestHash = tmhash.Sum([]byte("TESTING HASH"))
TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
UpgradePath = commitmenttypes.NewMerklePath([]string{"upgrade", upgradetypes.KeyUpgradedClient})
ConnectionVersion = connectiontypes.GetCompatibleEncodedVersions()[0]
MockAcknowledgement = mock.MockAcknowledgement
@ -196,6 +199,31 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) {
return proof, clienttypes.NewHeight(epoch, uint64(res.Height)+1)
}
// QueryUpgradeProof performs an abci query with the given key and returns the proto encoded merkle proof
// for the query and the height at which the proof will succeed on a tendermint verifier.
func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height) {
res := chain.App.Query(abci.RequestQuery{
Path: "store/upgrade/key",
Height: int64(height - 1),
Data: upgradetypes.UpgradedClientKey(),
Prove: true,
})
merkleProof := commitmenttypes.MerkleProof{
Proof: res.ProofOps,
}
proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof)
require.NoError(chain.t, err)
epoch := clienttypes.ParseChainID(chain.ChainID)
// proof height + 1 is returned as the proof created corresponds to the height the proof
// was created in the IAVL tree. Tendermint and subsequently the clients that rely on it
// have heights 1 above the IAVL tree. Thus we return proof height + 1
return proof, clienttypes.NewHeight(epoch, uint64(res.Height+1))
}
// QueryClientStateProof performs and abci query for a client state
// stored with a given clientID and returns the ClientState along with the proof
func (chain *TestChain) QueryClientStateProof(clientID string) (exported.ClientState, []byte) {
@ -392,7 +420,7 @@ func (chain *TestChain) ConstructMsgCreateClient(counterparty *TestChain, client
clientState = ibctmtypes.NewClientState(
counterparty.ChainID, DefaultTrustLevel, TrustingPeriod, UnbondingPeriod, MaxClockDrift,
height, commitmenttypes.GetSDKSpecs(),
false, false,
&UpgradePath, false, false,
)
consensusState = counterparty.LastHeader.ConsensusState()
case SoloMachine:

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ package upgrade_test
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"testing"
@ -20,6 +21,8 @@ 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/02-client/types"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/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"
@ -224,16 +227,27 @@ 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: `, types.Plan{Name: "test", Time: ti}.String())
Info:
Upgraded IBC Client: no upgraded client provided`, types.Plan{Name: "test", Time: ti}.String())
require.Equal(t, `Upgrade Plan
Name: test
Height: 100
Info: `, types.Plan{Name: "test", Height: 100}.String())
Info:
Upgraded IBC Client: no upgraded client provided`, 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())
}
func VerifyNotDone(t *testing.T, newCtx sdk.Context, name string) {

View File

@ -17,6 +17,8 @@ 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/02-client/types"
ibcexported "github.com/cosmos/cosmos-sdk/x/ibc/exported"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
@ -52,6 +54,8 @@ func (k Keeper) SetUpgradeHandler(name string, upgradeHandler types.UpgradeHandl
// ScheduleUpgrade schedules an upgrade based on the specified plan.
// If there is another Plan already scheduled, it will overwrite it
// (implicitly cancelling the current plan)
// ScheduleUpgrade will also write the upgraded client to the upgraded client path
// if an upgraded client is specified in the plan
func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error {
if err := plan.ValidateBasic(); err != nil {
return err
@ -69,13 +73,48 @@ func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgrade with name %s has already been completed", plan.Name)
}
bz := k.cdc.MustMarshalBinaryBare(&plan)
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryBare(&plan)
store.Set(types.PlanKey(), bz)
if plan.UpgradedClientState != nil {
clientState, err := clienttypes.UnpackClientState(plan.UpgradedClientState)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not unpack clientstate: %v", err)
}
return k.SetUpgradedClient(ctx, clientState)
}
// delete upgraded client key to remove any upgraded client set by outdated plan
store.Delete(types.UpgradedClientKey())
return nil
}
// SetUpgradedClient sets the expected upgraded client for the next version of this chain
func (k Keeper) SetUpgradedClient(ctx sdk.Context, cs ibcexported.ClientState) error {
// 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 := ctx.KVStore(k.storeKey)
store.Set(types.UpgradedClientKey(), bz)
return nil
}
// GetUpgradedClient gets the expected upgraded client for the next version of this chain
func (k Keeper) GetUpgradedClient(ctx sdk.Context) (ibcexported.ClientState, error) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.UpgradedClientKey())
if len(bz) == 0 {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "no upgraded client in store")
}
return clienttypes.UnmarshalClientState(k.cdc, bz)
}
// GetDoneHeight returns the height at which the given upgrade was executed
func (k Keeper) GetDoneHeight(ctx sdk.Context, name string) int64 {
store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte{types.DoneByte})

View File

@ -3,11 +3,17 @@ package keeper_test
import (
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"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/02-client/types"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
"github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
@ -17,6 +23,7 @@ type KeeperTestSuite struct {
homeDir string
app *simapp.SimApp
ctx sdk.Context
}
func (s *KeeperTestSuite) SetupTest() {
@ -28,6 +35,10 @@ func (s *KeeperTestSuite) SetupTest() {
s.T().Log("home dir:", homeDir)
s.homeDir = homeDir
s.app = app
s.ctx = app.BaseApp.NewContext(false, tmproto.Header{
Time: time.Now(),
Height: 10,
})
}
func (s *KeeperTestSuite) TestReadUpgradeInfoFromDisk() {
@ -48,6 +59,197 @@ func (s *KeeperTestSuite) TestReadUpgradeInfoFromDisk() {
s.Require().Equal(expected, ui)
}
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
setup func()
expPass bool
}{
{
name: "successful time schedule",
plan: types.Plan{
Name: "all-good",
Info: "some text here",
Time: s.ctx.BlockTime().Add(time.Hour),
},
setup: func() {},
expPass: true,
},
{
name: "successful height schedule",
plan: types.Plan{
Name: "all-good",
Info: "some text here",
Height: 123450000,
},
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{
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,
})
},
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{
Height: 123450000,
},
setup: func() {},
expPass: false,
},
{
name: "unsuccessful time schedule: due date in past",
plan: types.Plan{
Name: "all-good",
Info: "some text here",
Time: s.ctx.BlockTime(),
},
setup: func() {},
expPass: false,
},
{
name: "unsuccessful height schedule: due date in past",
plan: types.Plan{
Name: "all-good",
Info: "some text here",
Height: 1,
},
setup: func() {},
expPass: false,
},
{
name: "unsuccessful schedule: schedule already executed",
plan: types.Plan{
Name: "all-good",
Info: "some text here",
Height: 123450000,
},
setup: func() {
s.app.UpgradeKeeper.SetUpgradeHandler("all-good", func(_ sdk.Context, _ types.Plan) {})
s.app.UpgradeKeeper.ApplyUpgrade(s.ctx, types.Plan{
Name: "all-good",
Info: "some text here",
Height: 123450000,
})
},
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 {
tc := tc
s.Run(tc.name, func() {
// reset suite
s.SetupTest()
// setup test case
tc.setup()
err := s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, tc.plan)
if tc.expPass {
s.Require().NoError(err, "valid test case failed")
if tc.plan.UpgradedClientState != nil {
got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx)
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)
s.Require().Error(err)
s.Require().Nil(got)
}
} else {
s.Require().Error(err, "invalid test case passed")
}
})
}
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

View File

@ -19,6 +19,9 @@ const (
PlanByte = 0x0
// DoneByte is a prefix for to look up completed upgrade plan by name
DoneByte = 0x1
// KeyUpgradedClient is the key under which upgraded client is stored in the upgrade store
KeyUpgradedClient = "upgradedClient"
)
// PlanKey is the key under which the current plan is saved
@ -26,3 +29,10 @@ const (
func PlanKey() []byte {
return []byte{PlanByte}
}
// UpgradedClientKey is the key under which the upgraded client state is saved
// Connecting IBC chains can verify against the upgraded client in this path before
// upgrading their clients
func UpgradedClientKey() []byte {
return []byte(KeyUpgradedClient)
}

View File

@ -5,17 +5,31 @@ 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/02-client/types"
ibcexported "github.com/cosmos/cosmos-sdk/x/ibc/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 = fmt.Sprintf("%s", upgradedClient)
}
return fmt.Sprintf(`Upgrade Plan
Name: %s
%s
Info: %s`, p.Name, dueUp, p.Info)
Info: %s
Upgraded IBC Client: %s`, p.Name, dueUp, p.Info, upgradedClientStr)
}
// ValidateBasic does basic validation of a Plan
@ -32,6 +46,9 @@ func (p Plan) ValidateBasic() error {
if !p.Time.IsZero() && p.Height != 0 {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "cannot set both time and height")
}
if !p.Time.IsZero() && p.UpgradedClientState != nil {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "IBC chain upgrades must only set height")
}
return nil
}
@ -54,3 +71,14 @@ func (p Plan) DueAt() string {
}
return fmt.Sprintf("height: %d", p.Height)
}
// 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)
}

View File

@ -1,6 +1,7 @@
package types
import (
"fmt"
"testing"
"time"
@ -9,6 +10,9 @@ import (
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -21,6 +25,9 @@ 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 Plan
expect string
@ -31,7 +38,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",
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",
},
"with height": {
p: Plan{
@ -39,13 +46,23 @@ 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",
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: 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{}),
},
"neither": {
p: Plan{
Name: "almost-empty",
},
expect: "Upgrade Plan\n Name: almost-empty\n Height: 0\n Info: ",
expect: "Upgrade Plan\n Name: almost-empty\n Height: 0\n Info: \n Upgraded IBC Client: no upgraded client provided",
},
}
@ -59,6 +76,9 @@ 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 Plan
valid bool
@ -71,6 +91,15 @@ func TestPlanValid(t *testing.T) {
},
valid: true,
},
"proper ibc upgrade": {
p: Plan{
Name: "ibc-all-good",
Info: "some text here",
Height: 123450000,
UpgradedClientState: cs,
},
valid: true,
},
"proper by height": {
p: Plan{
Name: "all-good",
@ -95,6 +124,15 @@ func TestPlanValid(t *testing.T) {
Height: -12345,
},
},
"time due date defined for IBC plan": {
p: 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 {

View File

@ -5,6 +5,7 @@ package types
import (
fmt "fmt"
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"
@ -46,6 +47,12 @@ 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{} }
@ -170,30 +177,34 @@ func init() {
}
var fileDescriptor_ccf2a7d4d7b48dca = []byte{
// 368 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0xbf, 0x4e, 0xf3, 0x30,
0x14, 0xc5, 0xe3, 0xaf, 0xf9, 0x2a, 0xea, 0x6e, 0x56, 0x55, 0xa2, 0x0a, 0x9c, 0xa8, 0x62, 0xe8,
0x00, 0x8e, 0x5a, 0x24, 0x84, 0x18, 0xcb, 0x8e, 0xaa, 0x00, 0x0b, 0x12, 0x83, 0x93, 0xba, 0x69,
0x44, 0x12, 0x47, 0xb1, 0xcb, 0x9f, 0x17, 0x60, 0xa5, 0x8f, 0xc0, 0xe3, 0x74, 0xec, 0xd8, 0x09,
0x68, 0xbb, 0xf0, 0x18, 0x28, 0x76, 0x82, 0x18, 0x18, 0x99, 0x72, 0xcf, 0xd5, 0x2f, 0xe7, 0x9e,
0x9b, 0x5c, 0x78, 0x10, 0x70, 0x91, 0x70, 0xe1, 0xce, 0xb2, 0x30, 0xa7, 0x63, 0xe6, 0xde, 0xf7,
0x7d, 0x26, 0x69, 0xbf, 0xd2, 0x24, 0xcb, 0xb9, 0xe4, 0xa8, 0xad, 0x29, 0x52, 0x75, 0x4b, 0xaa,
0xd3, 0x0a, 0x79, 0xc8, 0x15, 0xe2, 0x16, 0x95, 0xa6, 0x3b, 0x76, 0xc8, 0x79, 0x18, 0x33, 0x57,
0x29, 0x7f, 0x36, 0x71, 0x65, 0x94, 0x30, 0x21, 0x69, 0x92, 0x69, 0xa0, 0xfb, 0x0c, 0xa0, 0x39,
0x8a, 0x69, 0x8a, 0x10, 0x34, 0x53, 0x9a, 0x30, 0x0b, 0x38, 0xa0, 0xd7, 0xf0, 0x54, 0x8d, 0x4e,
0xa1, 0x59, 0xf0, 0xd6, 0x3f, 0x07, 0xf4, 0x9a, 0x83, 0x0e, 0xd1, 0x66, 0xa4, 0x32, 0x23, 0x57,
0x95, 0xd9, 0x70, 0x67, 0xf1, 0x66, 0x1b, 0xf3, 0x77, 0x1b, 0x78, 0xea, 0x0d, 0xd4, 0x86, 0xf5,
0x29, 0x8b, 0xc2, 0xa9, 0xb4, 0x6a, 0x0e, 0xe8, 0xd5, 0xbc, 0x52, 0x15, 0x53, 0xa2, 0x74, 0xc2,
0x2d, 0x53, 0x4f, 0x29, 0xea, 0x33, 0xf3, 0xf3, 0xd5, 0x06, 0xdd, 0x17, 0x00, 0x77, 0x2f, 0xf9,
0x44, 0x3e, 0xd0, 0x9c, 0x5d, 0xeb, 0xdd, 0x46, 0x39, 0xcf, 0xb8, 0xa0, 0x31, 0x6a, 0xc1, 0xff,
0x32, 0x92, 0x71, 0x15, 0x4e, 0x0b, 0xe4, 0xc0, 0xe6, 0x98, 0x89, 0x20, 0x8f, 0x32, 0x19, 0xf1,
0x54, 0x85, 0x6c, 0x78, 0x3f, 0x5b, 0xe8, 0x04, 0x9a, 0x59, 0x4c, 0x53, 0x95, 0xa1, 0x39, 0xd8,
0x23, 0xbf, 0x7f, 0x3a, 0x52, 0xec, 0x3f, 0x34, 0x8b, 0x0d, 0x3c, 0xc5, 0x97, 0x89, 0x6e, 0xe1,
0xfe, 0x39, 0x4d, 0x03, 0x16, 0xff, 0x71, 0x2c, 0x6d, 0x3f, 0xbc, 0x58, 0xac, 0xb1, 0xb1, 0x5a,
0x63, 0x63, 0xb1, 0xc1, 0x60, 0xb9, 0xc1, 0xe0, 0x63, 0x83, 0xc1, 0x7c, 0x8b, 0x8d, 0xe5, 0x16,
0x1b, 0xab, 0x2d, 0x36, 0x6e, 0x0e, 0xc3, 0x48, 0x4e, 0x67, 0x3e, 0x09, 0x78, 0xe2, 0x96, 0xb7,
0xa1, 0x1f, 0x47, 0x62, 0x7c, 0xe7, 0x3e, 0x7e, 0x1f, 0x8a, 0x7c, 0xca, 0x98, 0xf0, 0xeb, 0xea,
0xb7, 0x1c, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xdc, 0xda, 0x23, 0xdb, 0x47, 0x02, 0x00, 0x00,
// 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,
}
func (this *Plan) Equal(that interface{}) bool {
@ -227,6 +238,9 @@ 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 {
@ -306,6 +320,18 @@ 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)
@ -318,12 +344,12 @@ func (m *Plan) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x18
}
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
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
}
i -= n1
i = encodeVarintUpgrade(dAtA, i, uint64(n1))
i -= n2
i = encodeVarintUpgrade(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x12
if len(m.Name) > 0 {
@ -450,6 +476,10 @@ 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
}
@ -640,6 +670,42 @@ 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:])