Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add UpgradeChain and UpgradeClient endpoint test functions #1169

Closed
wants to merge 10 commits into from
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* (testing) [\#1169](https://github.com/cosmos/ibc-go/pull/1169) Add `UpgradeChain` and `UpgradeClient` helper functions to the testing `Endpoint` structure.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo, update changelog entry


### Features

### Bug Fixes
Expand Down
80 changes: 80 additions & 0 deletions testing/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/stretchr/testify/require"

clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
Expand Down Expand Up @@ -492,6 +493,85 @@ func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error {
return endpoint.Chain.sendMsgs(timeoutOnCloseMsg)
}

// UpgradeChain performs a IBC client upgrade using the provided client state.
Copy link
Contributor

@seantking seantking Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mega nit: an IBC

// The chainID within the client state will have its revision number incremented by 1.
// The counterparty client will be upgraded if it exists.
func (endpoint *Endpoint) UpgradeChain(clientState *ibctmtypes.ClientState) error {
Copy link
Contributor

@seantking seantking Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be useful to pass revision number as a parameter rather than incrementing 🤔

// increment revision number in chainID
revisionNumber := clienttypes.ParseChainID(clientState.ChainId)
newChainID, err := clienttypes.SetRevisionNumber(clientState.ChainId, revisionNumber+1)
if err != nil {
// current chainID is not in revision format
newChainID = clientState.ChainId + "-1"
}

clientState.ChainId = newChainID

// set upgraded client state
bz := clienttypes.MustMarshalClientState(endpoint.Chain.App.AppCodec(), clientState)
endpoint.Chain.GetSimApp().UpgradeKeeper.SetUpgradedClient(endpoint.Chain.GetContext(), endpoint.Chain.GetContext().BlockHeight(), bz)

// set upgraded consensus state
consensusState := &ibctmtypes.ConsensusState{
Copy link
Member

@damiannolan damiannolan Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to include a root/app hash?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, the consensus state is set for the next block to be produced under the new chain id so the root hash cannot be known before hand

Timestamp: endpoint.Chain.GetContext().BlockTime(),
NextValidatorsHash: endpoint.Chain.GetContext().BlockHeader().NextValidatorsHash,
}

bz = clienttypes.MustMarshalConsensusState(endpoint.Chain.App.AppCodec(), consensusState)
endpoint.Chain.GetSimApp().IBCKeeper.ClientKeeper.SetUpgradedConsensusState(endpoint.Chain.GetContext(), endpoint.Chain.GetContext().BlockHeight(), bz)

// commit changes so they are stored in state
endpoint.Chain.NextBlock()

endpoint.Chain.ChainID = newChainID
endpoint.Chain.CurrentHeader.ChainID = newChainID

if endpoint.Counterparty.ClientID != "" {

}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops, forgot to add endpoint.UpgradeClient call

return nil
}

func (endpoint *Endpoint) UpgradeClient(upgradeHeight int64) error {
// ensure our client is up to date
err := endpoint.UpdateClient()
if err != nil {
return err
}

clientStateBz, found := endpoint.Counterparty.Chain.GetSimApp().IBCKeeper.ClientKeeper.GetUpgradedClient(endpoint.Counterparty.Chain.GetContext(), upgradeHeight)
require.True(endpoint.Chain.T, found)

clientState := clienttypes.MustUnmarshalClientState(endpoint.Counterparty.Chain.App.AppCodec(), clientStateBz)

consensusStateBz, found := endpoint.Counterparty.Chain.GetSimApp().IBCKeeper.ClientKeeper.GetUpgradedConsensusState(endpoint.Counterparty.Chain.GetContext(), upgradeHeight)
require.True(endpoint.Chain.T, found)

consensusState := clienttypes.MustUnmarshalConsensusState(endpoint.Counterparty.Chain.App.AppCodec(), consensusStateBz)

// query proof for the client state on the counterparty
clientKey := upgradetypes.UpgradedClientKey(upgradeHeight)
proofUpgradeClient, _ := endpoint.Counterparty.QueryProof(clientKey)

// query proof for the consensus state on the counterparty
consensusKey := upgradetypes.UpgradedConsStateKey(upgradeHeight)
proofUpgradeConsState, _ := endpoint.Counterparty.QueryProof(consensusKey)

// upgrade counterparty client
msg, err := clienttypes.NewMsgUpgradeClient(
endpoint.Counterparty.ClientID, clientState, consensusState, proofUpgradeClient, proofUpgradeConsState, endpoint.Chain.SenderAccount.GetAddress().String(),
)
require.NoError(endpoint.Chain.T, err)

if _, err := endpoint.Chain.SendMsgs(msg); err != nil {
return err
}

return nil

}

// SetChannelClosed sets a channel state to CLOSED.
func (endpoint *Endpoint) SetChannelClosed() error {
channel := endpoint.GetChannel()
Expand Down